Create a testable branch for WINE 4.18

This commit is contained in:
Justin Miller 2024-04-09 15:48:19 -07:00 committed by GitHub
parent e85ef799fe
commit 504c753e0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
222 changed files with 93598 additions and 20340 deletions

View file

@ -513,7 +513,7 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\HotFix",,0x00000012
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IME Compatibility",,0x00000012
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\IMM","IME File",2,"msctfime.ime"
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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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 */

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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"

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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"

View file

@ -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)

View file

@ -0,0 +1,2 @@
@ stdcall D3D10CoreCreateDevice(ptr ptr long long ptr)
@ stdcall D3D10CoreRegisterLayers()

View file

@ -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;
}

View file

@ -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"

View file

@ -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)

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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 <assert.h>
#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 */

File diff suppressed because it is too large Load diff

View file

@ -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);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -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"

File diff suppressed because it is too large Load diff

View file

@ -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))
{

View file

@ -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)

View file

@ -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 @@ done:
/***********************************************************************
* 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);

View file

@ -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 */

File diff suppressed because it is too large Load diff

View file

@ -20,8 +20,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#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;

View file

@ -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,

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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();

View file

@ -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))
{

View file

@ -21,7 +21,6 @@
*
*/
#include "config.h"
#include "initguid.h"
#include "d3d9_private.h"

View file

@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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();

View file

@ -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;
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;

View file

@ -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"
@ -50,7 +49,6 @@ 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 */
@ -58,7 +56,6 @@ static struct enum_device_entry
"WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D",
"Wine D3D7 T&L HAL",
&IID_IDirect3DTnLHalDevice,
0,
},
/* HAL device */
@ -66,7 +63,6 @@ static struct enum_device_entry
"WINE Direct3D7 Hardware acceleration using WineD3D",
"Direct3D HAL",
&IID_IDirect3DHALDevice,
0,
},
/* RGB device */
@ -74,7 +70,6 @@ static struct enum_device_entry
"WINE Direct3D7 RGB Software Emulation using WineD3D",
"Wine D3D7 RGB",
&IID_IDirect3DRGBDevice,
D3DDEVCAPS_HWTRANSFORMANDLIGHT,
},
};
@ -367,44 +362,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);
for (i = 0; i < ddraw->numConvertedDecls; ++i)
{
wined3d_vertex_declaration_decref(ddraw->decls[i].decl);
}
heap_free(ddraw->decls);
ddraw->numConvertedDecls = 0;
wined3d_swapchain_decref(ddraw->wined3d_swapchain);
ddraw->wined3d_swapchain = NULL;
if (!(ddraw->flags & DDRAW_NO3D))
/* Free the d3d window if one was created. */
if (ddraw->d3d_window && ddraw->d3d_window != ddraw->dest_window)
{
UINT i;
for (i = 0; i < ddraw->numConvertedDecls; ++i)
{
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;
}
}
ddraw->flags &= ~DDRAW_D3D_INITIALIZED;
}
else
{
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 +546,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 +590,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 +601,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 +615,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 +628,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 +884,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 +905,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))
@ -1247,7 +1217,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 +1308,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 |
@ -1439,28 +1412,6 @@ 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
*
@ -1479,10 +1430,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);
DDCAPS caps;
WINED3DCAPS winecaps;
HRESULT hr;
DDSCAPS2 ddscaps = {0, 0, 0, {0}};
struct wined3d_caps winecaps;
DDCAPS caps;
HRESULT hr;
TRACE("iface %p, driver_caps %p, hel_caps %p.\n", iface, DriverCaps, HELCaps);
@ -1543,8 +1494,6 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD
caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps;
IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps);
if(DriverCaps)
{
DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps);
@ -1675,11 +1624,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 +1719,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 +2243,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();
@ -3245,97 +3196,46 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags,
{
struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
struct ddraw_surface *surf;
DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH);
BOOL all, nomatch;
DDSURFACEDESC2 desc;
struct list *entry, *entry2;
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 (Flags & DDENUMSURFACES_CANBECREATED)
wined3d_mutex_lock();
/* Use the _SAFE enumeration, the app may destroy enumerated surfaces */
LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list)
{
IDirectDrawSurface7 *surface;
DDSURFACEDESC2 testdesc;
HRESULT hr;
surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry);
if (match_flags != DDENUMSURFACES_MATCH)
return DDERR_INVALIDPARAMS;
if (!DDSD)
return DDERR_INVALIDPARAMS;
memcpy(&testdesc, DDSD, sizeof(testdesc));
if (!(testdesc.dwFlags & DDSD_WIDTH))
if (!surf->iface_count)
{
testdesc.dwFlags |= DDSD_WIDTH;
testdesc.dwWidth = 512;
}
if (!(testdesc.dwFlags & DDSD_HEIGHT))
{
testdesc.dwFlags |= DDSD_HEIGHT;
testdesc.dwHeight = 512;
WARN("Not enumerating surface %p because it doesn't have any references.\n", surf);
continue;
}
hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL);
if (SUCCEEDED(hr))
if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc)))
{
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)
{
surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry);
if (!surf->iface_count)
TRACE("Enumerating surface %p.\n", surf);
desc = surf->surface_desc;
IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface);
if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_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();
return DD_OK;
}
}
wined3d_mutex_unlock();
}
else
return DDERR_INVALIDPARAMS;
wined3d_mutex_unlock();
return DD_OK;
}
@ -3731,7 +3631,6 @@ 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;
@ -3748,15 +3647,11 @@ 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)
{
@ -4126,52 +4021,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->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) &&
fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT)))
if (!fds || !fdr)
return DDERR_INVALIDPARAMS;
if ((fds->dwFlags & D3DFDS_COLORMODEL)
&& fds->dcmColorModel != D3DCOLOR_RGB)
if (fds->dwSize != sizeof(*fds))
{
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 search structure size %u.\n", fds->dwSize);
return DDERR_INVALIDPARAMS;
}
if (fdr->dwSize != sizeof(*fdr) && fdr->dwSize != sizeof(*fdr2) && fdr->dwSize != sizeof(*fdr1))
{
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;
}
}
@ -4184,22 +4100,31 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
ddraw_d3dcaps1_from_7(&desc1, &desc7);
fdr->guid = IID_D3DDEVICE_WineD3D;
if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT1))
/* Note that "device_desc_size" doesn't necessarily have any relation to
* the actual structure size. However, this matches the behaviour of
* Windows since at least Windows 2000. */
if (fdr->dwSize == sizeof(*fdr1))
{
D3DFINDDEVICERESULT1 *fdr1 = (D3DFINDDEVICERESULT1 *)fdr;
memcpy(&fdr1->ddHwDesc, &desc1, sizeof(fdr1->ddHwDesc));
memcpy(&fdr1->ddSwDesc, &desc1, sizeof(fdr1->ddSwDesc));
fdr1 = (struct ddraw_find_device_result_v1 *)fdr;
memcpy(&fdr1->hw_desc, &desc1, sizeof(fdr1->hw_desc));
fdr1->hw_desc.dwSize = device_desc_size;
memcpy(&fdr1->sw_desc, &desc1, sizeof(fdr1->sw_desc));
fdr1->sw_desc.dwSize = device_desc_size;
}
else if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT2))
else if (fdr->dwSize == sizeof(*fdr2))
{
D3DFINDDEVICERESULT2 *fdr2 = (D3DFINDDEVICERESULT2 *)fdr;
memcpy(&fdr2->ddHwDesc, &desc1, sizeof(fdr2->ddHwDesc));
memcpy(&fdr2->ddSwDesc, &desc1, sizeof(fdr2->ddSwDesc));
fdr2 = (struct ddraw_find_device_result_v2 *)fdr;
memcpy(&fdr2->hw_desc, &desc1, sizeof(fdr2->hw_desc));
fdr2->hw_desc.dwSize = device_desc_size;
memcpy(&fdr2->sw_desc, &desc1, sizeof(fdr2->sw_desc));
fdr2->sw_desc.dwSize = device_desc_size;
}
else
{
fdr->ddHwDesc = desc1;
fdr->ddHwDesc.dwSize = device_desc_size;
fdr->ddSwDesc = desc1;
fdr->ddSwDesc.dwSize = device_desc_size;
}
TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n");
@ -4207,22 +4132,52 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd
return D3D_OK;
}
static HRESULT WINAPI d3d2_FindDevice(IDirect3D2 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr)
static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fds, D3DFINDDEVICERESULT *fdr)
{
struct ddraw *ddraw = impl_from_IDirect3D2(iface);
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 d3d3_FindDevice(&ddraw->IDirect3D3_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 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));
}
/*****************************************************************************
@ -4257,7 +4212,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, riid, target, (IUnknown *)surface, 7, &object, NULL)))
if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL)))
{
*device = &object->IDirect3DDevice7_iface;
}
@ -4286,7 +4241,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid,
return CLASS_E_NOAGGREGATION;
wined3d_mutex_lock();
if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL)))
{
*device = &device_impl->IDirect3DDevice3_iface;
}
@ -4312,7 +4267,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, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL)))
{
*device = &device_impl->IDirect3DDevice2_iface;
}
@ -4484,8 +4439,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 +4464,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 =
{
@ -4684,7 +4639,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl =
ddraw2_GetAvailableVidMem,
};
static struct IDirectDrawVtbl ddraw1_vtbl =
static const struct IDirectDrawVtbl ddraw1_vtbl =
{
/* IUnknown */
ddraw1_QueryInterface,
@ -4925,18 +4880,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 +4917,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 +4933,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 +4962,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 +5015,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);

View file

@ -21,6 +21,7 @@
#include <assert.h>
#include <limits.h>
#include <math.h>
#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
@ -64,7 +66,9 @@ struct FvfToDecl
#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
| WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
| WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
| WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT)
| WINED3D_LEGACY_CUBEMAP_FILTERING)
#define DDRAW_MAX_ACTIVE_LIGHTS 32
enum ddraw_device_state
{
@ -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,9 +352,11 @@ 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,
HRESULT d3d_device_create(struct ddraw *ddraw, 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;
@ -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

View file

@ -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();
@ -1854,7 +1854,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface,
return DDERR_INVALIDCAPS;
}
if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
if (!(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 (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
if (!(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 (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target_impl);
IDirectDrawSurface_AddRef(target);
@ -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;
fixup_texture_alpha_op(device);
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 (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;
}
@ -3469,9 +3430,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 +3622,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 +3880,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 +4249,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 +4266,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 +4363,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 +4380,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 +4482,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);
return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device->IDirect3DDevice7_iface, PrimitiveType,
&vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount, Flags);
if (!(stride = get_flexible_vertex_size(vb->fvf)))
return D3D_OK;
return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device->IDirect3DDevice7_iface, primitive_type,
&vb->IDirect3DVertexBuffer7_iface, 0, vb->size / stride, indices, index_count, flags);
}
/*****************************************************************************
@ -4770,7 +4793,6 @@ 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);
@ -4778,10 +4800,10 @@ static HRESULT d3d_device7_SetTexture(IDirect3DDevice7 *iface,
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,45 +4830,15 @@ 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;
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)
{
/* 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 = 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;
}
/* 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();
@ -5164,10 +5156,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 +5304,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 +5317,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 +5341,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 +5364,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 +5375,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 +5607,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 +5672,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 +5686,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 +5792,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 +5852,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 +5988,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))
@ -6903,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, BOOL hw,
static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw,
struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown)
{
static const D3DMATRIX ident =
@ -6926,7 +6956,6 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B
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;
@ -6972,23 +7001,22 @@ 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;
}
HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
HRESULT d3d_device_create(struct ddraw *ddraw, 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, 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;
TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
ddraw, target, version, device, outer_unknown);
if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
|| (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
@ -7003,18 +7031,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 (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
WARN("Surface %p is not in video memory.\n", target);
return D3DERR_SURFACENOTINVIDMEM;
}
if (ddraw->d3ddevice)
@ -7029,7 +7057,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su
return DDERR_OUTOFMEMORY;
}
if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown)))
if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown)))
{
WARN("Failed to initialize device, hr %#x.\n", hr);
heap_free(object);

View file

@ -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;
@ -308,10 +293,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer,
ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags);
if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
{
static int once;
if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
}
FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n");
if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n");
@ -321,21 +303,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 +320,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 +582,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 +614,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 +638,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 +646,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 +678,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))
{

View file

@ -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->light.dwFlags & D3DLIGHT_ACTIVE)
if (!light->active_viewport || !light->active_viewport->active_device
|| light->active_viewport->active_device->current_viewport != light->active_viewport)
{
IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, FALSE);
light->light.dwFlags &= ~D3DLIGHT_ACTIVE;
assert(!light->active_light_index);
return;
}
device = light->active_viewport->active_device;
if (light->active_light_index)
{
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;

View file

@ -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);
@ -865,9 +852,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
* an application would unload ddraw from the WM_DESTROY handler for
* that window, it would return to unmapped memory and die. Apparently
* this is supposed to work on Windows. */
/* ReactOS r61844: Comment out usage of GET_MODULE_HANDLE_EX_FLAG_PIN because it doesn't work */
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS /*| GET_MODULE_HANDLE_EX_FLAG_PIN*/,
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
(const WCHAR *)&ddraw_self, &ddraw_self))
ERR("Failed to get own module handle.\n");

View file

@ -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);

View file

@ -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();

View file

@ -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,15 +37,22 @@ 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 ddraw *ddraw = surface->ddraw;
struct wined3d_texture *dst_texture;
HDC surface_dc, screen_dc;
int x, y, w, h;
HRESULT hr;
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);
@ -63,15 +67,25 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
if (w <= 0 || h <= 0)
return DD_OK;
if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
if (surface->ddraw->swapchain_window)
{
/* Nothing to do, we control the frontbuffer, or at least the parts we
* care about. */
if (read)
return DD_OK;
return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
if (swap_interval)
dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0);
else
dst_texture = surface->ddraw->wined3d_frontbuffer;
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)))
@ -209,7 +223,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface,
{
HRESULT hr;
if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface,
if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface,
1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
{
This->device1 = NULL;
@ -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);
@ -2311,9 +2377,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h
HRESULT hr;
TRACE("iface %p, dc %p.\n", iface, hdc);
#ifdef __REACTOS__
GdiFlush();
#endif
wined3d_mutex_lock();
if (!surface->dc)
{
@ -2323,7 +2387,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 +3734,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 +3775,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 +4362,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 +4429,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 +4523,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)
@ -5189,46 +5247,6 @@ 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
*
@ -5250,7 +5268,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);
RECT src_rect, dst_rect;
struct wined3d_resource *dst_resource, *src_resource;
HRESULT hr;
TRACE("iface %p, src_texture %p.\n", iface, src_texture);
@ -5263,60 +5281,90 @@ 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 (;;)
{
DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc;
struct ddraw_palette *dst_pal, *src_pal;
DDSURFACEDESC *src_desc, *dst_desc;
TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat,
&dst_surface->surface_desc.u4.ddpfPixelFormat))
/* 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)
{
struct ddraw_palette *dst_pal, *src_pal;
PALETTEENTRY palent[256];
/* Get the palettes */
dst_pal = dst_surface->palette;
src_pal = src_surface->palette;
if (src_pal)
if (!dst_pal)
{
PALETTEENTRY palent[256];
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);
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 one surface on the other */
dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc);
src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc);
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;
/* 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;
}
/* Suppress the ALLOCONLOAD flag */
dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
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;
}
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);
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;
}
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 (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);
wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx);
wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx);
}
if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
@ -5329,11 +5377,12 @@ 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();
@ -5563,7 +5612,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl =
ddraw_surface2_PageUnlock,
};
static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
{
/* IUnknown */
ddraw_surface1_QueryInterface,
@ -5755,11 +5804,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 +5991,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 +6076,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 +6091,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 +6145,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 +6188,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 +6215,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 +6304,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 +6365,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 +6485,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;

View file

@ -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);

View file

@ -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();

View file

@ -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);
}
if (!device)
{
WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
return D3DERR_VIEWPORTHASNODEVICE;
}
wined3d_mutex_lock();
This->use_vp2 = 0;
memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
/* 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;
if (This->active_device)
if (device->version > 1)
{
IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_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_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, &current_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<<i;
light_impl->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, 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 D3DVIEWPORT2 size %u.\n", vp->dwSize);
return DDERR_INVALIDPARAMS;
}
if (TRACE_ON(ddraw))
{
TRACE(" getting D3DVIEWPORT2 :\n");
_dump_D3DVIEWPORT2(lpData);
_dump_D3DVIEWPORT2(vp);
}
if (!device)
{
WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
return D3DERR_VIEWPORTHASNODEVICE;
}
wined3d_mutex_lock();
This->use_vp2 = 1;
memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
if (This->active_device)
if (device->version > 1)
{
IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_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, &current_viewport)))
{
if (current_viewport == iface)
viewport_activate(viewport, FALSE);
IDirect3DViewport3_Release(current_viewport);
}
wined3d_mutex_unlock();
@ -1132,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((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface);
return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface);
}
struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface)
@ -1140,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((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface);
return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface);
}
void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw)
@ -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);
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}

View file

@ -0,0 +1,255 @@
#ifndef __WINE_DXGI_PRIVATE_H
#define __WINE_DXGI_PRIVATE_H
#include "wine/debug.h"
#include "wine/heap.h"
#include <assert.h>
#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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -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"

View file

@ -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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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");
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_START) {
ctx->fogstart = (float) param;
} else if(pname == GL_FOG_END) {
ctx->fogend = (float) param;
}
}
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");
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_START) {
ctx->fogstart = (float) *param;
} else if(pname == GL_FOG_END) {
ctx->fogend = (float) *param;
}
}
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");
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
{
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->fogstart = param;
} else if(pname == GL_FOG_END) {
ctx->fogend = param;
}
}
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;

File diff suppressed because it is too large Load diff

View file

@ -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,

View file

@ -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;

View file

@ -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);
}

Some files were not shown because too many files have changed in this diff Show more