diff options
author | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 18:58:34 +0000 |
---|---|---|
committer | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 18:58:34 +0000 |
commit | 4a2a30ea291ad9386468e46faf86f2c9a355e16a (patch) | |
tree | 3d41ca2d30b3dc135ff99d17471f3d25beb4482a /o3d | |
parent | f58c8cc4dd6d74524a668880929c95b63c6588af (diff) | |
download | chromium_src-4a2a30ea291ad9386468e46faf86f2c9a355e16a.zip chromium_src-4a2a30ea291ad9386468e46faf86f2c9a355e16a.tar.gz chromium_src-4a2a30ea291ad9386468e46faf86f2c9a355e16a.tar.bz2 |
Dynamically loads d3d9 and d3dx9 dlls on Windows.
It's so chrome.exe does not have to load these dlls even when there's no 3D going on.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/237004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27224 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/d3d9_utils.h | 11 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/effect_d3d9.cc | 64 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/effect_d3d9.h | 12 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc | 84 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/gapi_d3d9.h | 75 | ||||
-rw-r--r-- | o3d/plugin/plugin.gyp | 12 | ||||
-rw-r--r-- | o3d/tests/tests.gyp | 24 |
7 files changed, 219 insertions, 63 deletions
diff --git a/o3d/command_buffer/service/win/d3d9/d3d9_utils.h b/o3d/command_buffer/service/win/d3d9/d3d9_utils.h index cffccda..ff1e8f3 100644 --- a/o3d/command_buffer/service/win/d3d9/d3d9_utils.h +++ b/o3d/command_buffer/service/win/d3d9/d3d9_utils.h @@ -96,17 +96,6 @@ inline D3DCOLOR RGBAToD3DCOLOR(const RGBA &color) { FloatToClampedByte(color.alpha)); } -inline bool VerifyHResult(HRESULT hr, const char* file, int line, - const char* call) { - if (FAILED(hr)) { - DLOG(ERROR) << "DX Error in file " << file - << " line " << line << L": " - << DXGetErrorStringA(hr) << L": " << call; - return false; - } - return true; -} - static bool D3DSemanticToCBSemantic( D3DDECLUSAGE semantic, unsigned int semantic_index, diff --git a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc index 49672bf..3268ab2 100644 --- a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc +++ b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc @@ -68,10 +68,12 @@ static void LogFXError(LPD3DXBUFFER error_buffer) { } } -EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect, +EffectD3D9::EffectD3D9(GAPID3D9 *gapi, + ID3DXEffect *d3d_effect, ID3DXConstantTable *fs_constant_table, IDirect3DVertexShader9 *d3d_vertex_shader) - : d3d_effect_(d3d_effect), + : gapi_(gapi), + d3d_effect_(d3d_effect), fs_constant_table_(fs_constant_table), d3d_vertex_shader_(d3d_vertex_shader), sync_parameters_(false) { @@ -111,15 +113,15 @@ EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, ID3DXEffect *d3d_effect = NULL; LPD3DXBUFFER error_buffer; IDirect3DDevice9 *device = gapi->d3d_device(); - if (D3DXCreateEffect(device, - prepared_effect.c_str(), - prepared_effect.size(), - NULL, - NULL, - 0, - NULL, - &d3d_effect, - &error_buffer) != D3D_OK) { + if (gapi->D3DXCreateEffect(device, + prepared_effect.c_str(), + prepared_effect.size(), + NULL, + NULL, + 0, + NULL, + &d3d_effect, + &error_buffer) != D3D_OK) { LogFXError(error_buffer); return NULL; } @@ -150,8 +152,8 @@ EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, D3DXPASS_DESC pass_desc; HR(d3d_effect->GetPassDesc(pass, &pass_desc)); ID3DXConstantTable *table = NULL; - HR(D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, - &table)); + HR(gapi->D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, + &table)); if (!table) { LOG(ERROR) << "Could not get the constant table."; d3d_effect->Release(); @@ -167,20 +169,20 @@ EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, return NULL; } - return new EffectD3D9(d3d_effect, table, d3d_vertex_shader); + return new EffectD3D9(gapi, d3d_effect, table, d3d_vertex_shader); } // Begins rendering with the effect, setting all the appropriate states. -bool EffectD3D9::Begin(GAPID3D9 *gapi) { +bool EffectD3D9::Begin() { UINT numpasses; HR(d3d_effect_->Begin(&numpasses, 0)); HR(d3d_effect_->BeginPass(0)); sync_parameters_ = false; - return SetSamplers(gapi); + return SetSamplers(); } // Terminates rendering with the effect, resetting all the appropriate states. -void EffectD3D9::End(GAPID3D9 *gapi) { +void EffectD3D9::End() { HR(d3d_effect_->EndPass()); HR(d3d_effect_->End()); } @@ -278,23 +280,23 @@ EffectParamD3D9 *EffectD3D9::CreateParamByName(const char *name) { return EffectParamD3D9::Create(this, handle); } -bool EffectD3D9::CommitParameters(GAPID3D9 *gapi) { +bool EffectD3D9::CommitParameters() { if (sync_parameters_) { sync_parameters_ = false; d3d_effect_->CommitChanges(); - return SetSamplers(gapi); + return SetSamplers(); } else { return true; } } -bool EffectD3D9::SetSamplers(GAPID3D9 *gapi) { - IDirect3DDevice9 *d3d_device = gapi->d3d_device(); +bool EffectD3D9::SetSamplers() { + IDirect3DDevice9 *d3d_device = gapi_->d3d_device(); bool result = true; for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { - SamplerD3D9 *sampler = gapi->GetSampler(samplers_[i]); + SamplerD3D9 *sampler = gapi_->GetSampler(samplers_[i]); if (sampler) { - result &= sampler->ApplyStates(gapi, i); + result &= sampler->ApplyStates(gapi_, i); } else { HR(d3d_device->SetTexture(i, NULL)); } @@ -312,13 +314,13 @@ bool EffectD3D9::SetStreams() { d3d_vertex_shader_->GetFunction(function.get(), &size); UINT num_semantics; - HR(D3DXGetShaderInputSemantics(function.get(), - NULL, - &num_semantics)); + HR(gapi_->D3DXGetShaderInputSemantics(function.get(), + NULL, + &num_semantics)); scoped_array<D3DXSEMANTIC> semantics(new D3DXSEMANTIC[num_semantics]); - HR(D3DXGetShaderInputSemantics(function.get(), - semantics.get(), - &num_semantics)); + HR(gapi_->D3DXGetShaderInputSemantics(function.get(), + semantics.get(), + &num_semantics)); streams_.resize(num_semantics); for (UINT i = 0; i < num_semantics; ++i) { @@ -655,7 +657,7 @@ BufferSyncInterface::ParseError GAPID3D9::GetStreamDesc( void GAPID3D9::DirtyEffect() { if (validate_effect_) return; DCHECK(current_effect_); - current_effect_->End(this); + current_effect_->End(); current_effect_ = NULL; validate_effect_ = true; } @@ -668,7 +670,7 @@ bool GAPID3D9::ValidateEffect() { current_effect_ = effects_.Get(current_effect_id_); if (!current_effect_) return false; validate_effect_ = false; - return current_effect_->Begin(this); + return current_effect_->Begin(); } } // namespace command_buffer diff --git a/o3d/command_buffer/service/win/d3d9/effect_d3d9.h b/o3d/command_buffer/service/win/d3d9/effect_d3d9.h index f4f64dd..bdccc72 100644 --- a/o3d/command_buffer/service/win/d3d9/effect_d3d9.h +++ b/o3d/command_buffer/service/win/d3d9/effect_d3d9.h @@ -79,7 +79,8 @@ class EffectParamD3D9: public EffectParam { // D3D9 version of Effect. class EffectD3D9 : public Effect { public: - EffectD3D9(ID3DXEffect *d3d_effect, + EffectD3D9(GAPID3D9 *gapi, + ID3DXEffect *d3d_effect, ID3DXConstantTable *fs_constant_table, IDirect3DVertexShader9 *d3d_vertex_shader); virtual ~EffectD3D9(); @@ -89,12 +90,12 @@ class EffectD3D9 : public Effect { const String &vertex_program_entry, const String &fragment_program_entry); // Applies the effect states (vertex shader, pixel shader) to D3D. - bool Begin(GAPID3D9 *gapi); + bool Begin(); // Resets the effect states (vertex shader, pixel shader) to D3D. - void End(GAPID3D9 *gapi); + void End(); // Commits parameters to D3D, if they were modified while the effect is // active. - bool CommitParameters(GAPID3D9 *gapi); + bool CommitParameters(); // Gets the number of parameters in the effect. unsigned int GetParamCount(); @@ -115,10 +116,11 @@ class EffectD3D9 : public Effect { // Unlinks a param into this effect. void UnlinkParam(EffectParamD3D9 *param); // Sets sampler states. - bool SetSamplers(GAPID3D9 *gapi); + bool SetSamplers(); // Sets streams vector. bool SetStreams(); + GAPID3D9* gapi_; ID3DXEffect *d3d_effect_; IDirect3DVertexShader9 *d3d_vertex_shader_; ID3DXConstantTable *fs_constant_table_; diff --git a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc index 5c71793..8b20707 100644 --- a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc +++ b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc @@ -38,7 +38,9 @@ namespace o3d { namespace command_buffer { GAPID3D9::GAPID3D9() - : d3d_(NULL), + : d3d_module_(NULL), + d3dx_module_(NULL), + d3d_(NULL), d3d_device_(NULL), hwnd_(NULL), current_vertex_struct_(0), @@ -53,15 +55,25 @@ GAPID3D9::GAPID3D9() back_buffer_surface_(NULL), back_buffer_depth_surface_(NULL), current_surface_id_(kInvalidResource), - current_depth_surface_id_(kInvalidResource) {} + current_depth_surface_id_(kInvalidResource), + direct3d_create9_(NULL), + get_shader_constant_table_(NULL), + create_effect_(NULL), + get_shader_input_semantics_(NULL) {} GAPID3D9::~GAPID3D9() {} // Initializes a D3D interface and device, and sets basic states. bool GAPID3D9::Initialize() { - d3d_ = Direct3DCreate9(D3D_SDK_VERSION); + if (!FindDirect3DFunctions()) { + Destroy(); + return false; + } + + d3d_ = Direct3DCreate(D3D_SDK_VERSION); if (NULL == d3d_) { LOG(ERROR) << "Failed to create the initial D3D9 Interface"; + Destroy(); return false; } d3d_device_ = NULL; @@ -129,6 +141,7 @@ bool GAPID3D9::Initialize() { &d3dpp, &d3d_device_))) { LOG(ERROR) << "Failed to create the D3D Device"; + Destroy(); return false; } // initialise the d3d graphics state. @@ -157,6 +170,18 @@ void GAPID3D9::Destroy() { d3d_->Release(); d3d_ = NULL; } + if (d3dx_module_) { + FreeLibrary(d3dx_module_); + d3dx_module_ = NULL; + get_shader_constant_table_ = NULL; + create_effect_ = NULL; + get_shader_input_semantics_ = NULL; + } + if (d3d_module_) { + FreeLibrary(d3d_module_); + d3d_module_ = NULL; + direct3d_create9_ = NULL; + } } // Begins the frame. @@ -220,6 +245,55 @@ BufferSyncInterface::ParseError GAPID3D9::SetVertexStruct(ResourceID id) { return BufferSyncInterface::kParseNoError; } +bool GAPID3D9::FindDirect3DFunctions() { + d3d_module_ = LoadLibrary(TEXT("d3d9.dll")); + if (NULL == d3d_module_) { + LOG(ERROR) << "Failed to load d3d9.dll"; + return false; + } + + direct3d_create9_ = reinterpret_cast<Direct3DCreate9Proc>( + GetProcAddress(d3d_module_, "Direct3DCreate9")); + if (NULL == direct3d_create9_) { + LOG(ERROR) << "Failed to find Direct3DCreate9 in d3d9.dll"; + Destroy(); + return false; + } + + d3dx_module_ = LoadLibrary(TEXT("d3dx9_36.dll")); + if (NULL == d3d_module_) { + LOG(ERROR) << "Failed to load d3dx9_36.dll"; + return false; + } + + get_shader_constant_table_ = reinterpret_cast<D3DXGetShaderConstantTableProc>( + GetProcAddress(d3dx_module_, "D3DXGetShaderConstantTable")); + if (NULL == get_shader_constant_table_) { + LOG(ERROR) << "Failed to find D3DXGetShaderConstantTable in d3dx9_36.dll"; + Destroy(); + return false; + } + + create_effect_ = reinterpret_cast<D3DXCreateEffectProc>( + GetProcAddress(d3dx_module_, "D3DXCreateEffect")); + if (NULL == create_effect_) { + LOG(ERROR) << "Failed to find D3DXCreateEffect in d3dx9_36.dll"; + Destroy(); + return false; + } + + get_shader_input_semantics_ = + reinterpret_cast<D3DXGetShaderInputSemanticsProc>( + GetProcAddress(d3dx_module_, "D3DXGetShaderInputSemantics")); + if (NULL == get_shader_input_semantics_) { + LOG(ERROR) << "Failed to find D3DXGetShaderInputSemantics in d3dx9_36.dll"; + Destroy(); + return false; + } + + return true; +} + // Sets in D3D the input streams of the current vertex struct. bool GAPID3D9::ValidateStreams() { DCHECK(validate_streams_); @@ -268,7 +342,7 @@ BufferSyncInterface::ParseError GAPID3D9::Draw( return BufferSyncInterface::kParseInvalidArguments; } DCHECK(current_effect_); - if (!current_effect_->CommitParameters(this)) { + if (!current_effect_->CommitParameters()) { return BufferSyncInterface::kParseInvalidArguments; } if (first + count > max_vertices_) { @@ -298,7 +372,7 @@ BufferSyncInterface::ParseError GAPID3D9::DrawIndexed( return BufferSyncInterface::kParseInvalidArguments; } DCHECK(current_effect_); - if (!current_effect_->CommitParameters(this)) { + if (!current_effect_->CommitParameters()) { return BufferSyncInterface::kParseInvalidArguments; } if ((min_index >= max_vertices_) || (max_index > max_vertices_)) { diff --git a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h index f4a9b4a..7f6e97e 100644 --- a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h +++ b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h @@ -392,7 +392,50 @@ class GAPID3D9 : public GAPIInterface { }
EffectD3D9 *current_effect() { return current_effect_; }
+
+ // Direct3D functions cannot be called directly because the DLLs are loaded
+ // dynamically via LoadLibrary. If you need to add another Direct3D function
+ // add another function here, a typedef matching the signature and a member
+ // variable of that type below. Then add code to FindDirect3DFunctions to
+ // get the address of that function out of the DLL and assign it to the
+ // member variable. Be careful to initialize the value of the variable to
+ // NULL in the constructor and to set it to again NULL in Destroy.
+
+ IDirect3D9* Direct3DCreate(UINT version) { + DCHECK(direct3d_create9_); + return direct3d_create9_(version); + } + + HRESULT D3DXGetShaderConstantTable(const DWORD* function, + LPD3DXCONSTANTTABLE* table) { + DCHECK(get_shader_constant_table_); + return get_shader_constant_table_(function, table); + } + + HRESULT D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
+ LPCVOID src_data,
+ UINT src_data_len,
+ CONST D3DXMACRO * defines,
+ LPD3DXINCLUDE include,
+ DWORD flags,
+ LPD3DXEFFECTPOOL pool,
+ LPD3DXEFFECT * effect,
+ LPD3DXBUFFER * compilation_errors) { + DCHECK(create_effect_); + return create_effect_(device, src_data, src_data_len, defines, include, + flags, pool, effect, compilation_errors); + } +
+ HRESULT D3DXGetShaderInputSemantics(const DWORD* function,
+ D3DXSEMANTIC* semantics,
+ UINT* count) {
+ DCHECK(get_shader_input_semantics_);
+ return get_shader_input_semantics_(function, semantics, count);
+ }
+
private:
+ bool FindDirect3DFunctions();
+
// Validates the current vertex struct to D3D, setting the streams.
bool ValidateStreams();
// Validates the current effect to D3D. This sends the effect states to D3D.
@@ -401,6 +444,12 @@ class GAPID3D9 : public GAPIInterface { // requires ValidateEffect() to be called before further draws occur.
void DirtyEffect();
+ // Module handle for d3d9.dll.
+ HMODULE d3d_module_;
+
+ // Module handle for d3dx9_n.dll
+ HMODULE d3dx_module_;
+
LPDIRECT3D9 d3d_;
LPDIRECT3DDEVICE9 d3d_device_;
HWND hwnd_;
@@ -424,6 +473,32 @@ class GAPID3D9 : public GAPIInterface { ResourceMap<SamplerD3D9> samplers_;
ResourceMap<RenderSurfaceD3D9> render_surfaces_;
ResourceMap<RenderDepthStencilSurfaceD3D9> depth_surfaces_;
+
+ typedef IDirect3D9* (WINAPI *Direct3DCreate9Proc)(UINT version); + Direct3DCreate9Proc direct3d_create9_;
+ + typedef HRESULT (WINAPI *D3DXGetShaderConstantTableProc)( + const DWORD* function, + LPD3DXCONSTANTTABLE* table); + D3DXGetShaderConstantTableProc get_shader_constant_table_; + + typedef HRESULT (WINAPI *D3DXCreateEffectProc)(
+ LPDIRECT3DDEVICE9 device,
+ LPCVOID src_data,
+ UINT src_data_len,
+ CONST D3DXMACRO * defines,
+ LPD3DXINCLUDE include,
+ DWORD flags,
+ LPD3DXEFFECTPOOL pool,
+ LPD3DXEFFECT * effect,
+ LPD3DXBUFFER * compilation_errors); + D3DXCreateEffectProc create_effect_;
+
+ typedef HRESULT (WINAPI *D3DXGetShaderInputSemanticsProc)(
+ const DWORD* function,
+ D3DXSEMANTIC* semantics,
+ UINT* count);
+ D3DXGetShaderInputSemanticsProc get_shader_input_semantics_;
};
} // namespace command_buffer
diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp index 22894b1..397dceb 100644 --- a/o3d/plugin/plugin.gyp +++ b/o3d/plugin/plugin.gyp @@ -214,17 +214,25 @@ }, }, ], - ['OS == "win" and (renderer == "d3d9" or cb_service == "d3d9")', + ['OS == "win" and renderer == "d3d9"', { 'link_settings': { 'libraries': [ - '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', '"$(DXSDK_DIR)/Lib/x86/d3dx9.lib"', '-ld3d9.lib', ], }, }, ], + ['OS == "win" and (renderer == "d3d9" or cb_service == "d3d9")', + { + 'link_settings': { + 'libraries': [ + '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', + ], + }, + }, + ], ], }, ], diff --git a/o3d/tests/tests.gyp b/o3d/tests/tests.gyp index fc3c5ce..a4cc2a9 100644 --- a/o3d/tests/tests.gyp +++ b/o3d/tests/tests.gyp @@ -166,22 +166,28 @@ 'editbin /SUBSYSTEM:CONSOLE $(OutDir)/$(TargetFileName)', }, ], - ['OS == "win" and (renderer == "d3d9" or cb_service == "d3d9")', + ['OS == "win" and renderer == "d3d9"', { 'sources': [ 'common/win/dxcapture.cc', ], + 'link_settings': { + 'libraries': [ + '"$(DXSDK_DIR)/Lib/x86/d3dx9.lib"', + 'd3d9.lib', + ], + }, + }, + ], + ['OS == "win" and (renderer == "d3d9" or cb_service == "d3d9")', + { 'include_dirs': [ '"$(DXSDK_DIR)/Include"', ], - 'msvs_settings': { - 'VCLinkerTool': { - 'AdditionalDependencies': [ - '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', - '"$(DXSDK_DIR)/Lib/x86/d3dx9.lib"', - 'd3d9.lib', - ], - }, + 'link_settings': { + 'libraries': [ + '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', + ], }, }, ], |