/* * Direct3D 9 * * Copyright 2002-2003 Jason Edmeades * Copyright 2002-2003 Raphael Junqueira * Copyright 2005 Oliver Stieber * * 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 "initguid.h" #include "d3d9_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d9); static int D3DPERF_event_level = 0; void WINAPI DebugSetMute(void) { /* nothing to do */ } IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version) { struct d3d9 *object; TRACE("sdk_version %#x.\n", sdk_version); if (!(object = heap_alloc_zero(sizeof(*object)))) return NULL; if (!d3d9_init(object, FALSE)) { WARN("Failed to initialize d3d9.\n"); heap_free(object); return NULL; } TRACE("Created d3d9 object %p.\n", object); return (IDirect3D9 *)&object->IDirect3D9Ex_iface; } HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9Ex **d3d9ex) { struct d3d9 *object; TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex); if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; if (!d3d9_init(object, TRUE)) { WARN("Failed to initialize d3d9.\n"); heap_free(object); return D3DERR_NOTAVAILABLE; } TRACE("Created d3d9 object %p.\n", object); *d3d9ex = &object->IDirect3D9Ex_iface; return D3D_OK; } /* The callback is called on any error encountered during validation, including * improper IDirect3DShaderValidator9 method calls. * - "file" and "line" are passed through directly from Instruction(). "line" * is provably 32-bit, as 64-bit values passed to Instruction() will be * truncated. * - "arg3" has been observed to be at least 0, 2, and 6. The integer size is * not known. * - "message_id" is a numeric error code. fxc.exe adds 5000 before printing * it. The integer size is not known. * - "context" is passed through directly from Begin(). * * Improper calls to IDirect3DShaderValidator9 methods, or other errors not * generated by specific Instruction() calls, yield NULL as the file, and * either 0 or -1 as the line. * * The callback return type is not known, but programs (fxc.exe, The Sims 2) * seem to consistently return 0. * * The interface and method names below are derived from the messages that * native d3d9 prints on said improper method calls. * * Calls to Begin(), Instruction(), End() have been observed to return S_OK and * E_FAIL. E_FAIL is not always returned if an error message is handed to the * callback. */ typedef HRESULT (WINAPI *shader_validator_cb)(const char *file, int line, DWORD_PTR arg3, DWORD_PTR message_id, const char *message, void *context); typedef struct IDirect3DShaderValidator9 IDirect3DShaderValidator9; struct IDirect3DShaderValidator9Vtbl { HRESULT (WINAPI *QueryInterface)(IDirect3DShaderValidator9 *iface, REFIID iid, void **out); ULONG (WINAPI *AddRef)(IDirect3DShaderValidator9 *iface); ULONG (WINAPI *Release)(IDirect3DShaderValidator9 *iface); HRESULT (WINAPI *Begin)(IDirect3DShaderValidator9 *iface, shader_validator_cb callback, void *context, DWORD_PTR arg3); HRESULT (WINAPI *Instruction)(IDirect3DShaderValidator9 *iface, const char *file, int line, const DWORD *tokens, DWORD token_count); HRESULT (WINAPI *End)(IDirect3DShaderValidator9 *iface); }; struct IDirect3DShaderValidator9 { const struct IDirect3DShaderValidator9Vtbl *vtbl; }; static HRESULT WINAPI shader_validator_QueryInterface(IDirect3DShaderValidator9 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); *out = NULL; return E_NOINTERFACE; } static ULONG WINAPI shader_validator_AddRef(IDirect3DShaderValidator9 *iface) { TRACE("iface %p.\n", iface); return 2; } static ULONG WINAPI shader_validator_Release(IDirect3DShaderValidator9 *iface) { TRACE("iface %p.\n", iface); return 1; } /* The size and type of the third argument is not known. The Sims 2 passes 0; * fxc.exe passes 1. */ static HRESULT WINAPI shader_validator_Begin(IDirect3DShaderValidator9 *iface, shader_validator_cb callback, void *context, DWORD_PTR arg3) { FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3); return S_OK; } /* - "file" and "line" are passed directly through to the callback. * - "tokens" comprises a single instruction; the caller must determine its * length. * - "token_count" is in DWORDs. */ static HRESULT WINAPI shader_validator_Instruction(IDirect3DShaderValidator9 *iface, const char *file, int line, const DWORD *tokens, DWORD token_count) { FIXME("iface %p, file %s, line %u, tokens %p, token_count %u, stub!\n", iface, debugstr_a(file), line, tokens, token_count); return S_OK; } static HRESULT WINAPI shader_validator_End(IDirect3DShaderValidator9 *iface) { FIXME("iface %p, stub!\n", iface); return S_OK; } static const struct IDirect3DShaderValidator9Vtbl shader_validator_vtbl = { shader_validator_QueryInterface, shader_validator_AddRef, shader_validator_Release, shader_validator_Begin, shader_validator_Instruction, shader_validator_End, }; static IDirect3DShaderValidator9 shader_validator = {&shader_validator_vtbl}; IDirect3DShaderValidator9 * WINAPI Direct3DShaderValidatorCreate9(void) { TRACE("Returning validator %p.\n", &shader_validator); return &shader_validator; } /*********************************************************************** * D3DPERF_BeginEvent (D3D9.@) */ int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, const WCHAR *name) { TRACE("color 0x%08x, name %s.\n", color, debugstr_w(name)); return D3DPERF_event_level++; } /*********************************************************************** * D3DPERF_EndEvent (D3D9.@) */ int WINAPI D3DPERF_EndEvent(void) { TRACE("(void) : stub\n"); return --D3DPERF_event_level; } /*********************************************************************** * D3DPERF_GetStatus (D3D9.@) */ DWORD WINAPI D3DPERF_GetStatus(void) { FIXME("(void) : stub\n"); return 0; } /*********************************************************************** * D3DPERF_SetOptions (D3D9.@) * */ void WINAPI D3DPERF_SetOptions(DWORD options) { FIXME("(%#x) : stub\n", options); } /*********************************************************************** * D3DPERF_QueryRepeatFrame (D3D9.@) */ BOOL WINAPI D3DPERF_QueryRepeatFrame(void) { FIXME("(void) : stub\n"); return FALSE; } /*********************************************************************** * D3DPERF_SetMarker (D3D9.@) */ void WINAPI D3DPERF_SetMarker(D3DCOLOR color, const WCHAR *name) { FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); } /*********************************************************************** * D3DPERF_SetRegion (D3D9.@) */ void WINAPI D3DPERF_SetRegion(D3DCOLOR color, const WCHAR *name) { FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); } void d3d9_resource_cleanup(struct d3d9_resource *resource) { wined3d_private_store_cleanup(&resource->private_store); } HRESULT d3d9_resource_free_private_data(struct d3d9_resource *resource, const GUID *guid) { struct wined3d_private_data *entry; wined3d_mutex_lock(); entry = wined3d_private_store_get_private_data(&resource->private_store, guid); if (!entry) { wined3d_mutex_unlock(); return D3DERR_NOTFOUND; } wined3d_private_store_free_private_data(&resource->private_store, entry); wined3d_mutex_unlock(); return D3D_OK; } HRESULT d3d9_resource_get_private_data(struct d3d9_resource *resource, const GUID *guid, void *data, DWORD *data_size) { const struct wined3d_private_data *stored_data; DWORD size_in; HRESULT hr; wined3d_mutex_lock(); stored_data = wined3d_private_store_get_private_data(&resource->private_store, guid); if (!stored_data) { hr = D3DERR_NOTFOUND; goto done; } size_in = *data_size; *data_size = stored_data->size; if (!data) { hr = D3D_OK; goto done; } if (size_in < stored_data->size) { hr = D3DERR_MOREDATA; goto done; } if (stored_data->flags & WINED3DSPD_IUNKNOWN) IUnknown_AddRef(stored_data->content.object); memcpy(data, stored_data->content.data, stored_data->size); hr = D3D_OK; done: wined3d_mutex_unlock(); return hr; } void d3d9_resource_init(struct d3d9_resource *resource) { resource->refcount = 1; wined3d_private_store_init(&resource->private_store); } HRESULT d3d9_resource_set_private_data(struct d3d9_resource *resource, const GUID *guid, const void *data, DWORD data_size, DWORD flags) { HRESULT hr; wined3d_mutex_lock(); hr = wined3d_private_store_set_private_data(&resource->private_store, guid, data, data_size, flags); wined3d_mutex_unlock(); return hr; }