summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 18:58:34 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 18:58:34 +0000
commit4a2a30ea291ad9386468e46faf86f2c9a355e16a (patch)
tree3d41ca2d30b3dc135ff99d17471f3d25beb4482a /o3d
parentf58c8cc4dd6d74524a668880929c95b63c6588af (diff)
downloadchromium_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.h11
-rw-r--r--o3d/command_buffer/service/win/d3d9/effect_d3d9.cc64
-rw-r--r--o3d/command_buffer/service/win/d3d9/effect_d3d9.h12
-rw-r--r--o3d/command_buffer/service/win/d3d9/gapi_d3d9.cc84
-rw-r--r--o3d/command_buffer/service/win/d3d9/gapi_d3d9.h75
-rw-r--r--o3d/plugin/plugin.gyp12
-rw-r--r--o3d/tests/tests.gyp24
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"',
+ ],
},
},
],