aboutsummaryrefslogtreecommitdiff
path: root/lib/win32/Effects11/EffectAPI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/win32/Effects11/EffectAPI.cpp')
-rw-r--r--lib/win32/Effects11/EffectAPI.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/lib/win32/Effects11/EffectAPI.cpp b/lib/win32/Effects11/EffectAPI.cpp
new file mode 100644
index 0000000000..69e1671b22
--- /dev/null
+++ b/lib/win32/Effects11/EffectAPI.cpp
@@ -0,0 +1,335 @@
+//--------------------------------------------------------------------------------------
+// File: EffectAPI.cpp
+//
+// Effect API entry point
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// http://go.microsoft.com/fwlink/p/?LinkId=271568
+//--------------------------------------------------------------------------------------
+
+#include "pchfx.h"
+
+#include <memory>
+
+using namespace D3DX11Effects;
+
+//-------------------------------------------------------------------------------------
+
+struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } };
+
+typedef public std::unique_ptr<void, handle_closer> ScopedHandle;
+
+inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }
+
+//-------------------------------------------------------------------------------------
+
+static HRESULT LoadBinaryFromFile( _In_z_ LPCWSTR pFileName, _Inout_ std::unique_ptr<uint8_t[]>& data, _Out_ uint32_t& size )
+{
+ // open the file
+#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
+ ScopedHandle hFile( safe_handle( CreateFile2( pFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ OPEN_EXISTING,
+ nullptr ) ) );
+#else
+ ScopedHandle hFile( safe_handle( CreateFileW( pFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr ) ) );
+#endif
+
+ if ( !hFile )
+ {
+ return HRESULT_FROM_WIN32( GetLastError() );
+ }
+
+ // Get the file size
+ LARGE_INTEGER FileSize = { 0 };
+
+#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
+ FILE_STANDARD_INFO fileInfo;
+ if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) )
+ {
+ return HRESULT_FROM_WIN32( GetLastError() );
+ }
+ FileSize = fileInfo.EndOfFile;
+#else
+ GetFileSizeEx( hFile.get(), &FileSize );
+#endif
+
+ // File is too big for 32-bit allocation or contains no data, so reject read
+ if ( !FileSize.LowPart || FileSize.HighPart > 0)
+ {
+ return E_FAIL;
+ }
+
+ // create enough space for the file data
+ data.reset( new uint8_t[ FileSize.LowPart ] );
+ if (!data)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ // read the data in
+ DWORD BytesRead = 0;
+ if (!ReadFile( hFile.get(),
+ data.get(),
+ FileSize.LowPart,
+ &BytesRead,
+ nullptr
+ ))
+ {
+ return HRESULT_FROM_WIN32( GetLastError() );
+ }
+
+ if (BytesRead < FileSize.LowPart)
+ {
+ return E_FAIL;
+ }
+
+ size = BytesRead;
+
+ return S_OK;
+}
+
+//--------------------------------------------------------------------------------------
+
+_Use_decl_annotations_
+HRESULT WINAPI D3DX11CreateEffectFromMemory(LPCVOID pData, SIZE_T DataLength, UINT FXFlags,
+ ID3D11Device *pDevice, ID3DX11Effect **ppEffect, LPCSTR srcName )
+{
+ if ( !pData || !DataLength || !pDevice || !ppEffect )
+ return E_INVALIDARG;
+
+#ifdef _M_X64
+ if ( DataLength > 0xFFFFFFFF )
+ return E_INVALIDARG;
+#endif
+
+ HRESULT hr = S_OK;
+
+ // Note that pData must point to a compiled effect, not HLSL
+ VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS) );
+ VH( ((CEffect*)(*ppEffect))->LoadEffect(pData, static_cast<uint32_t>(DataLength) ) );
+ VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, (srcName) ? srcName : "D3DX11Effect" ) );
+
+lExit:
+ if (FAILED(hr))
+ {
+ SAFE_RELEASE(*ppEffect);
+ }
+ return hr;
+}
+
+//--------------------------------------------------------------------------------------
+
+_Use_decl_annotations_
+HRESULT WINAPI D3DX11CreateEffectFromFile( LPCWSTR pFileName, UINT FXFlags, ID3D11Device *pDevice, ID3DX11Effect **ppEffect )
+{
+ if ( !pFileName || !pDevice || !ppEffect )
+ return E_INVALIDARG;
+
+ std::unique_ptr<uint8_t[]> fileData;
+ uint32_t size;
+ HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size );
+ if ( FAILED(hr) )
+ return hr;
+
+ hr = S_OK;
+
+ // Note that pData must point to a compiled effect, not HLSL
+ VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS) );
+ VH( ((CEffect*)(*ppEffect))->LoadEffect( fileData.get(), size ) );
+
+ // Create debug object name from input filename
+ CHAR strFileA[MAX_PATH];
+ int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
+ if ( !result )
+ {
+ DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName);
+ hr = E_FAIL;
+ goto lExit;
+ }
+
+ const CHAR* pstrName = strrchr( strFileA, '\\' );
+ if (!pstrName)
+ {
+ pstrName = strFileA;
+ }
+ else
+ {
+ pstrName++;
+ }
+
+ VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) );
+
+lExit:
+ if (FAILED(hr))
+ {
+ SAFE_RELEASE(*ppEffect);
+ }
+ return hr;
+}
+
+
+//--------------------------------------------------------------------------------------
+
+_Use_decl_annotations_
+HRESULT D3DX11CompileEffectFromMemory( LPCVOID pData, SIZE_T DataLength, LPCSTR srcName,
+ const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags,
+ ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors )
+{
+ if ( !pData || !DataLength || !pDevice || !ppEffect )
+ return E_INVALIDARG;
+
+ if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT )
+ {
+ DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" );
+ return E_NOTIMPL;
+ }
+
+ ID3DBlob *blob = nullptr;
+ HRESULT hr = D3DCompile( pData, DataLength, srcName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
+ if ( FAILED(hr) )
+ {
+ DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr );
+ return hr;
+ }
+
+ hr = S_OK;
+
+ VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) );
+ VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) );
+ SAFE_RELEASE( blob );
+
+ VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, (srcName) ? srcName : "D3DX11Effect" ) );
+
+lExit:
+ if (FAILED(hr))
+ {
+ SAFE_RELEASE(*ppEffect);
+ }
+ return hr;
+}
+
+//--------------------------------------------------------------------------------------
+
+_Use_decl_annotations_
+HRESULT D3DX11CompileEffectFromFile( LPCWSTR pFileName,
+ const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags,
+ ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors )
+{
+ if ( !pFileName || !pDevice || !ppEffect )
+ return E_INVALIDARG;
+
+ if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT )
+ {
+ DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" );
+ return E_NOTIMPL;
+ }
+
+ ID3DBlob *blob = nullptr;
+
+#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || ( (WINAPI_FAMILY != WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) ) )
+
+ HRESULT hr = D3DCompileFromFile( pFileName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
+ if ( FAILED(hr) )
+ {
+ DPF(0, "D3DCompileFromFile of fx_5_0 profile failed %08X: %S", hr, pFileName );
+ return hr;
+ }
+
+#else // D3D_COMPILER_VERSION < 46
+
+ std::unique_ptr<uint8_t[]> fileData;
+ uint32_t size;
+ HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size );
+ if ( FAILED(hr) )
+ {
+ DPF(0, "Failed to load effect file %08X: %S", hr, pFileName);
+ return hr;
+ }
+
+ // Create debug object name from input filename
+ CHAR strFileA[MAX_PATH];
+ int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
+ if ( !result )
+ {
+ DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName);
+ return E_FAIL;
+ }
+
+ const CHAR* pstrName = strrchr( strFileA, '\\' );
+ if (!pstrName)
+ {
+ pstrName = strFileA;
+ }
+ else
+ {
+ pstrName++;
+ }
+
+ hr = D3DCompile( fileData.get(), size, pstrName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
+ if ( FAILED(hr) )
+ {
+ DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr );
+ return hr;
+ }
+
+#endif // D3D_COMPILER_VERSION
+
+#ifdef _M_X64
+ if ( blob->GetBufferSize() > 0xFFFFFFFF )
+ {
+ SAFE_RELEASE( blob );
+ return E_FAIL;
+ }
+#endif // _M_X64
+
+ hr = S_OK;
+
+ VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) );
+ VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) );
+ SAFE_RELEASE( blob );
+
+#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || ( (WINAPI_FAMILY != WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) ) )
+ // Create debug object name from input filename
+ CHAR strFileA[MAX_PATH];
+ int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
+ if ( !result )
+ {
+ DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName);
+ hr = E_FAIL;
+ goto lExit;
+ }
+
+ const CHAR* pstrName = strrchr( strFileA, '\\' );
+ if (!pstrName)
+ {
+ pstrName = strFileA;
+ }
+ else
+ {
+ pstrName++;
+ }
+#endif
+
+ VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) );
+
+lExit:
+ if (FAILED(hr))
+ {
+ SAFE_RELEASE(*ppEffect);
+ }
+ return hr;
+}