diff options
author | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 02:39:33 +0000 |
---|---|---|
committer | petersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-26 02:39:33 +0000 |
commit | e73d4f7b1f150436dae5d589fd73c8d17c2dcb56 (patch) | |
tree | abdc8f4fba62512c716f14b67badd7993c0394fe /o3d/command_buffer | |
parent | a4369599f7e9c15c66bcf66cc1c9bd158666eea4 (diff) | |
download | chromium_src-e73d4f7b1f150436dae5d589fd73c8d17c2dcb56.zip chromium_src-e73d4f7b1f150436dae5d589fd73c8d17c2dcb56.tar.gz chromium_src-e73d4f7b1f150436dae5d589fd73c8d17c2dcb56.tar.bz2 |
Created new build target for opengl command buffer service, fixed various bugs in opengl command buffers service code until unit tests passed on windows.
Review URL: http://codereview.chromium.org/165279
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24415 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/command_buffer')
-rw-r--r-- | o3d/command_buffer/client/cross/effect_helper.cc | 1 | ||||
-rw-r--r-- | o3d/command_buffer/client/cross/effect_helper.h | 2 | ||||
-rw-r--r-- | o3d/command_buffer/common/cross/resource.h | 11 | ||||
-rw-r--r-- | o3d/command_buffer/service/build.scons | 66 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/effect_gl.cc | 292 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/effect_gl.h | 24 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/gapi_gl.cc | 301 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/gapi_gl.h | 32 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/geometry_gl.cc | 15 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gl/gl_utils.h | 13 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/plugin.cc | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/precompile.cc | 33 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/precompile.h | 62 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/big_test_main.cc | 22 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/effect_d3d9.cc | 3 |
15 files changed, 778 insertions, 101 deletions
diff --git a/o3d/command_buffer/client/cross/effect_helper.cc b/o3d/command_buffer/client/cross/effect_helper.cc index 1552e29..8302c14 100644 --- a/o3d/command_buffer/client/cross/effect_helper.cc +++ b/o3d/command_buffer/client/cross/effect_helper.cc @@ -111,6 +111,7 @@ bool EffectHelper::CreateEffectParameters(ResourceID effect_id, Desc *raw_desc = raw_descs + j; desc->data_type = raw_desc->data_type; desc->data_size = raw_desc->data_size; + desc->num_elements = raw_desc->num_elements; desc->cmd_desc_size = raw_desc->size; } } diff --git a/o3d/command_buffer/client/cross/effect_helper.h b/o3d/command_buffer/client/cross/effect_helper.h index 4c62487..d802e4a 100644 --- a/o3d/command_buffer/client/cross/effect_helper.h +++ b/o3d/command_buffer/client/cross/effect_helper.h @@ -55,6 +55,8 @@ class EffectHelper { String semantic; // The semantic of the param. effect_param::DataType data_type; // The data type of a param. unsigned int data_size; // The size of the data for a param. + int num_elements; // The number of array entries if the + // parameter is an array, 0 otherwise. unsigned int cmd_desc_size; // The size of the effect_param::Desc // structure (counting strings) for a // param. diff --git a/o3d/command_buffer/common/cross/resource.h b/o3d/command_buffer/common/cross/resource.h index 861d24f..215aa52 100644 --- a/o3d/command_buffer/common/cross/resource.h +++ b/o3d/command_buffer/common/cross/resource.h @@ -71,7 +71,8 @@ enum Flags { namespace vertex_struct { // Semantics for input data. enum Semantic { - POSITION, + UNKNOWN_SEMANTIC = -1, + POSITION = 0, NORMAL, COLOR, TEX_COORD, @@ -129,6 +130,8 @@ struct Desc { // the terminating nul character. Will always be // set even if the semantic doesn't fit into the // buffer. + Uint32 num_elements; // the number of entries if the parameter is an array + // 0 otherwise. DataType data_type; // the data type of the parameter. Uint32 data_size; // the size of the parameter data, in bytes. }; @@ -136,6 +139,12 @@ struct Desc { namespace effect_stream { struct Desc { + Desc() + : semantic(vertex_struct::UNKNOWN_SEMANTIC), + semantic_index(0) {} + Desc(Uint32 semantic, Uint32 semantic_index) + : semantic(semantic), + semantic_index(semantic_index) {} Uint32 semantic; // the semantic type Uint32 semantic_index; }; diff --git a/o3d/command_buffer/service/build.scons b/o3d/command_buffer/service/build.scons index c8e9292..8bd7e4f 100644 --- a/o3d/command_buffer/service/build.scons +++ b/o3d/command_buffer/service/build.scons @@ -40,9 +40,25 @@ INPUTS = [ 'cross/texture_utils.cc', ] +# Add a precompiled header declaration to the Windows environment. +if env['TARGET_PLATFORM'] == 'WINDOWS': + env.Append( + CCFLAGS = [ + '/Ylcommand_buffer', + '/FIcommand_buffer/service/cross/precompile.h', + ], + ) + pch, pch_obj = env.PCH('cross/precompile.cc') + env['PCH'] = pch + env['PCHSTOP'] = 'command_buffer/service/cross/precompile.h' +else: + pch_obj = 'cross/precompile.cc' + env.Append(CCFLAGS = [['-include', + 'command_buffer/service/cross/precompile.h']]) + # Build the big tests BIG_TEST_SERVER = [ - 'cross/big_test.cc', + 'cross/big_test.cc', ] # Add some flags and libraries to the build environment for the unit tests @@ -58,21 +74,35 @@ env.Append( ) if env['TARGET_PLATFORM'] == 'WINDOWS': - env.Append(CCFLAGS = [], - LIBS = [# System libs. - 'd3d9', - # TODO: remove link-time dependency on d3dx9, using - # dynamic loading instead. - 'd3dx9', - 'dxerr', - 'shell32'], - LINKFLAGS=['/SUBSYSTEM:CONSOLE']) - INPUTS += ['win/d3d9/effect_d3d9.cc', - 'win/d3d9/gapi_d3d9.cc', - 'win/d3d9/geometry_d3d9.cc', - 'win/d3d9/sampler_d3d9.cc', - 'win/d3d9/states_d3d9.cc', - 'win/d3d9/texture_d3d9.cc'] + if 'CB_SERVICE_D3D9' in env['CPPDEFINES']: + env.Append(CCFLAGS = [], + LIBS = [# System libs. + 'd3d9', + # TODO: remove link-time dependency on d3dx9, using + # dynamic loading instead. + 'd3dx9', + 'dxerr', + 'shell32'], + LINKFLAGS=['/SUBSYSTEM:CONSOLE']) + INPUTS += ['win/d3d9/effect_d3d9.cc', + 'win/d3d9/gapi_d3d9.cc', + 'win/d3d9/geometry_d3d9.cc', + 'win/d3d9/sampler_d3d9.cc', + 'win/d3d9/states_d3d9.cc', + 'win/d3d9/texture_d3d9.cc'] + elif 'CB_SERVICE_GL' in env['CPPDEFINES']: + env.Append(CCFLAGS = [], + LIBS = ['OpenGL32', 'glew32', 'cg', 'cgGL'], + LIBPATH = ['$CG_DIR/lib', '$GLEW_DIR/lib'], + CPPPATH = ['$CG_DIR/include', '$GLEW_DIR/include'], + LINKFLAGS=['/SUBSYSTEM:CONSOLE']) + INPUTS += ['cross/gl/effect_gl.cc', + 'cross/gl/gapi_gl.cc', + 'cross/gl/geometry_gl.cc', + 'cross/gl/sampler_gl.cc', + 'cross/gl/states_gl.cc', + 'cross/gl/texture_gl.cc'] + BIG_TEST_SERVER += ['win/big_test_main.cc'] elif env['TARGET_PLATFORM'] == 'LINUX': env.Append(LIBS = ['GL', 'GLEW', 'Cg', 'CgGL'], @@ -91,8 +121,8 @@ o3dcmdbuf_lib = env.ComponentLibrary('o3dCmdBuf_service', INPUTS) # TODO: why can't these be ComponentTestProgram? -# Create a target executable program called 'o3dCmdBuf_bigtest_server' from the list -# of big test server files. +# Create a target executable program called 'o3dCmdBuf_bigtest_server' from the +# list of big test server files. big_test_server = env.Program('o3dCmdBuf_bigtest_server', BIG_TEST_SERVER) # Copy the resulting executable to the Artifacts directory. diff --git a/o3d/command_buffer/service/cross/gl/effect_gl.cc b/o3d/command_buffer/service/cross/gl/effect_gl.cc index 9343d96..4e9da56 100644 --- a/o3d/command_buffer/service/cross/gl/effect_gl.cc +++ b/o3d/command_buffer/service/cross/gl/effect_gl.cc @@ -36,6 +36,7 @@ #include <map> #include "base/cross/std_functional.h" +#include "command_buffer/service/cross/gl/effect_gl.h" #include "command_buffer/service/cross/gl/gapi_gl.h" #include "command_buffer/service/cross/effect_utils.h" @@ -82,6 +83,8 @@ static effect_param::DataType CgTypeToCBType(CGtype cg_type) { case CG_SAMPLER3D: case CG_SAMPLERCUBE: return effect_param::SAMPLER; + case CG_TEXTURE: + return effect_param::TEXTURE; default : { DLOG(INFO) << "Cannot convert CGtype " << cgGetTypeString(cg_type) @@ -96,10 +99,15 @@ EffectParamGL *EffectParamGL::Create(EffectGL *effect, DCHECK(effect); const EffectGL::LowLevelParam &low_level_param = effect->low_level_params_[index]; - CGtype cg_type = - cgGetParameterType(EffectGL::GetEitherCgParameter(low_level_param)); + CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); + CGtype cg_type = cgGetParameterType(cg_param); + if (cg_type == CG_ARRAY) { + cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); + } effect_param::DataType type = CgTypeToCBType(cg_type); - if (type == effect_param::UNKNOWN) return NULL; + + if (type == effect_param::UNKNOWN) + return NULL; return new EffectParamGL(type, effect, index); } @@ -116,6 +124,7 @@ bool EffectParamGL::GetDesc(unsigned int size, void *data) { CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); const char *name = low_level_param.name; const char* semantic = cgGetParameterSemantic(cg_param); + int num_elements = cgGetArraySize(cg_param, 0); unsigned int name_size = name ? static_cast<unsigned int>(strlen(name)) + 1 : 0; unsigned int semantic_size = semantic ? @@ -130,6 +139,7 @@ bool EffectParamGL::GetDesc(unsigned int size, void *data) { desc->name_offset = 0; desc->name_size = name_size; desc->semantic_offset = 0; + desc->num_elements = num_elements; desc->semantic_size = semantic_size; unsigned int current_offset = sizeof(Desc); if (name && current_offset + name_size <= size) { @@ -154,6 +164,12 @@ bool EffectParamGL::SetData(GAPIGL *gapi, EffectGL::LowLevelParam &low_level_param = effect_->low_level_params_[low_level_param_index_]; + + if (low_level_param.num_elements != 0) { + DLOG(ERROR) << "Attempt to set array parameter to value."; + return false; + } + CGparameter vp_param = low_level_param.vp_param; CGparameter fp_param = low_level_param.fp_param; effect_param::DataType type = data_type(); @@ -202,7 +218,8 @@ bool EffectParamGL::SetData(GAPIGL *gapi, break; } case effect_param::SAMPLER: { - low_level_param.sampler_id = *static_cast<const ResourceID *>(data); + DCHECK_GE(low_level_param.sampler_ids.size(), 1); + low_level_param.sampler_ids[0] = *static_cast<const ResourceID *>(data); if (effect_ == gapi->current_effect()) { gapi->DirtyEffect(); } @@ -222,18 +239,18 @@ EffectGL::EffectGL(CGprogram vertex_program, } EffectGL::~EffectGL() { - for (ParamResourceList::iterator it = resource_params_.begin(); - it != resource_params_.end(); ++it) { + for (ParamList::iterator it = params_.begin(); + it != params_.end(); ++it) { (*it)->ResetEffect(); } } void EffectGL::LinkParam(EffectParamGL *param) { - resource_params_.push_back(param); + params_.push_back(param); } void EffectGL::UnlinkParam(EffectParamGL *param) { - std::remove(resource_params_.begin(), resource_params_.end(), param); + std::remove(params_.begin(), params_.end(), param); } // Rewrites vertex program assembly code to match GL semantics for clipping. @@ -406,11 +423,13 @@ int EffectGL::GetLowLevelParamIndexByName(const char *name) { return -1; } -void EffectGL::AddLowLevelParams(CGparameter cg_param, - bool vp) { - // Loop over all *leaf* parameters, visiting only CGparameters that have - // had storage allocated to them. - for (; cg_param != NULL; cg_param = cgGetNextLeafParameter(cg_param)) { +void EffectGL::AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp) { + // Iterate through parameters and add them to the vector of low level + // parameters, visiting only CGparameters that have had storage allocated to + // them, and add the params to the low_level_params_ vector. + for (CGparameter cg_param = cgGetFirstParameter(prog, name_space); + cg_param != NULL; + cg_param = cgGetNextParameter(cg_param)) { CGenum variability = cgGetParameterVariability(cg_param); if (variability != CG_UNIFORM) continue; @@ -421,20 +440,47 @@ void EffectGL::AddLowLevelParams(CGparameter cg_param, if (!name) continue; + CGtype cg_type = cgGetParameterType(cg_param); + + int num_elements; + if (cg_type == CG_ARRAY) { + num_elements = cgGetArraySize(cg_param, 0); + // Substitute the first element's type for our type.
+ cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); + } else { + num_elements = 0; + } + int index = GetLowLevelParamIndexByName(name); if (index < 0) { - LowLevelParam param = {name, NULL, NULL, kInvalidResource}; + LowLevelParam param; + param.name = name; + param.vp_param = NULL; + param.fp_param = NULL; + param.num_elements = num_elements; + index = low_level_params_.size(); - low_level_params_.push_back(param); - CGtype cg_type = cgGetParameterType(cg_param); if (cg_type == CG_SAMPLER || cg_type == CG_SAMPLER1D || cg_type == CG_SAMPLER2D || cg_type == CG_SAMPLER3D || cg_type == CG_SAMPLERCUBE) { sampler_params_.push_back(index); + if (num_elements == 0) { + param.sampler_ids.push_back(kInvalidResource); + } else { + param.sampler_ids.resize(num_elements); + std::vector<ResourceID>::iterator iter; + for (iter = param.sampler_ids.begin(); + iter != param.sampler_ids.end(); + ++iter) { + *iter = kInvalidResource; + } + } } + low_level_params_.push_back(param); } + if (vp) { low_level_params_[index].vp_param = cg_param; } else { @@ -443,29 +489,148 @@ void EffectGL::AddLowLevelParams(CGparameter cg_param, } } +typedef std::pair<String, effect_stream::Desc> SemanticMapElement; +typedef std::map<String, effect_stream::Desc> SemanticMap; + +// The map batween the semantics on vertex program varying parameters names +// and vertex attribute indices under the VP_30 profile. +SemanticMapElement semantic_map_array[] = { + SemanticMapElement("POSITION", + effect_stream::Desc(vertex_struct::POSITION, 0)), + SemanticMapElement("ATTR0", + effect_stream::Desc(vertex_struct::POSITION, 0)), + SemanticMapElement("BLENDWEIGHT", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("ATTR1", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("NORMAL", + effect_stream::Desc(vertex_struct::NORMAL, 0)), + SemanticMapElement("ATTR2", + effect_stream::Desc(vertex_struct::NORMAL, 0)), + SemanticMapElement("COLOR0", + effect_stream::Desc(vertex_struct::COLOR, 0)), + SemanticMapElement("DIFFUSE", + effect_stream::Desc(vertex_struct::COLOR, 0)), + SemanticMapElement("ATTR3", + effect_stream::Desc(vertex_struct::COLOR, 0)), + SemanticMapElement("COLOR1", + effect_stream::Desc(vertex_struct::COLOR, 1)), + SemanticMapElement("SPECULAR", + effect_stream::Desc(vertex_struct::COLOR, 1)), + SemanticMapElement("ATTR4", + effect_stream::Desc(vertex_struct::COLOR, 1)), + SemanticMapElement("TESSFACTOR", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("FOGCOORD", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("ATTR5", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("PSIZE", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("ATTR6", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("BLENDINDICES", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("ATTR7", + effect_stream::Desc(vertex_struct::UNKNOWN_SEMANTIC, 0)), + SemanticMapElement("TEXCOORD0", + effect_stream::Desc(vertex_struct::TEX_COORD, 0)), + SemanticMapElement("ATTR8", + effect_stream::Desc(vertex_struct::TEX_COORD, 0)), + SemanticMapElement("TEXCOORD1", + effect_stream::Desc(vertex_struct::TEX_COORD, 1)), + SemanticMapElement("ATTR9", + effect_stream::Desc(vertex_struct::TEX_COORD, 1)), + SemanticMapElement("TEXCOORD2", + effect_stream::Desc(vertex_struct::TEX_COORD, 2)), + SemanticMapElement("ATTR10", + effect_stream::Desc(vertex_struct::TEX_COORD, 2)), + SemanticMapElement("TEXCOORD3", + effect_stream::Desc(vertex_struct::TEX_COORD, 3)), + SemanticMapElement("ATTR11", + effect_stream::Desc(vertex_struct::TEX_COORD, 3)), + SemanticMapElement("TEXCOORD4", + effect_stream::Desc(vertex_struct::TEX_COORD, 4)), + SemanticMapElement("ATTR12", + effect_stream::Desc(vertex_struct::TEX_COORD, 4)), + SemanticMapElement("TEXCOORD5", + effect_stream::Desc(vertex_struct::TEX_COORD, 5)), + SemanticMapElement("ATTR13", + effect_stream::Desc(vertex_struct::TEX_COORD, 5)), + SemanticMapElement("TEXCOORD6", + effect_stream::Desc(vertex_struct::TEX_COORD, 6)), + SemanticMapElement("TANGENT", + effect_stream::Desc(vertex_struct::TEX_COORD, 6)), + SemanticMapElement("ATTR14", + effect_stream::Desc(vertex_struct::TEX_COORD, 7)), + SemanticMapElement("TEXCOORD7", + effect_stream::Desc(vertex_struct::TEX_COORD, 7)), + SemanticMapElement("BINORMAL", + effect_stream::Desc(vertex_struct::TEX_COORD, 8)), + SemanticMapElement("ATTR15", + effect_stream::Desc(vertex_struct::TEX_COORD, 8)) +}; + +static SemanticMap semantic_map(semantic_map_array, + semantic_map_array + + arraysize(semantic_map_array)); + void EffectGL::Initialize() { - AddLowLevelParams(cgGetFirstLeafParameter(vertex_program_, CG_PROGRAM), true); - AddLowLevelParams(cgGetFirstLeafParameter(vertex_program_, CG_GLOBAL), true); - AddLowLevelParams(cgGetFirstLeafParameter(fragment_program_, CG_PROGRAM), - false); - AddLowLevelParams(cgGetFirstLeafParameter(fragment_program_, CG_GLOBAL), - false); + AddLowLevelParams(vertex_program_, CG_PROGRAM, true); + AddLowLevelParams(vertex_program_, CG_GLOBAL, true); + AddLowLevelParams(fragment_program_, CG_PROGRAM, false); + AddLowLevelParams(fragment_program_, CG_GLOBAL, false); + + AddStreams(vertex_program_, CG_PROGRAM); + AddStreams(vertex_program_, CG_GLOBAL); +} + +// Loop over all leaf parameters, and find the ones that are bound to a +// semantic. +void EffectGL::AddStreams(CGprogram prog, CGenum name_space) { + for (CGparameter cg_param = cgGetFirstLeafParameter(prog, name_space); + cg_param != NULL; + cg_param = cgGetNextLeafParameter(cg_param)) { + CGenum variability = cgGetParameterVariability(cg_param); + if (variability != CG_VARYING) + continue; + CGenum direction = cgGetParameterDirection(cg_param); + if (direction != CG_IN) + continue; + const char* cg_semantic = cgGetParameterSemantic(cg_param); + if (cg_semantic == NULL) + continue; + + SemanticMap::iterator iter = semantic_map.find(String(cg_semantic)); + if (iter == semantic_map.end()) { + streams_.push_back(effect_stream::Desc( + vertex_struct::UNKNOWN_SEMANTIC, 0)); + } else { + streams_.push_back(iter->second); + } + } } // Begins rendering with the effect, setting all the appropriate states. bool EffectGL::Begin(GAPIGL *gapi) { cgGLBindProgram(vertex_program_); cgGLBindProgram(fragment_program_); + // sampler->ApplyStates will mess with the texture binding on unit 0, so we // do 2 passes. // First to set the sampler states on the texture for (unsigned int i = 0; i < sampler_params_.size(); ++i) { unsigned int param_index = sampler_params_[i]; - ResourceID id = low_level_params_[param_index].sampler_id; - if (id != kInvalidResource) { - SamplerGL *sampler = gapi->GetSampler(id); - if (!sampler->ApplyStates(gapi)) { - return false; + std::vector<ResourceID> &ids = low_level_params_[param_index].sampler_ids; + for (std::vector<ResourceID>::iterator iter = ids.begin(); + iter != ids.end(); + ++iter) { + ResourceID id = *iter; + if (id != kInvalidResource) { + SamplerGL *sampler = gapi->GetSampler(id); + if (!sampler->ApplyStates(gapi)) { + return false; + } } } } @@ -473,15 +638,24 @@ bool EffectGL::Begin(GAPIGL *gapi) { for (unsigned int i = 0; i < sampler_params_.size(); ++i) { unsigned int param_index = sampler_params_[i]; const LowLevelParam &ll_param = low_level_params_[param_index]; - ResourceID id = ll_param.sampler_id; - if (id != kInvalidResource) { - SamplerGL *sampler = gapi->GetSampler(id); - GLuint gl_texture = sampler->gl_texture(); - cgGLSetTextureParameter(ll_param.fp_param, gl_texture); - cgGLEnableTextureParameter(ll_param.fp_param); - } else { - cgGLSetTextureParameter(ll_param.fp_param, 0); - cgGLDisableTextureParameter(ll_param.fp_param); + std::vector<ResourceID> &ids = low_level_params_[param_index].sampler_ids; + // TODO(petersont): Rewrite the following so it handles arrays of samplers + // instead of simply bailing. + if (cgGetParameterType(ll_param.fp_param) == CG_ARRAY) + return false; + for (std::vector<ResourceID>::iterator iter = ids.begin(); + iter != ids.end(); + ++iter) { + ResourceID id = *iter; + if (id != kInvalidResource) { + SamplerGL *sampler = gapi->GetSampler(id); + GLuint gl_texture = sampler->gl_texture(); + cgGLSetTextureParameter(ll_param.fp_param, gl_texture); + cgGLEnableTextureParameter(ll_param.fp_param); + } else { + cgGLSetTextureParameter(ll_param.fp_param, 0); + cgGLDisableTextureParameter(ll_param.fp_param); + } } } return true; @@ -496,19 +670,39 @@ unsigned int EffectGL::GetParamCount() const { return low_level_params_.size(); } +// Gets the number of input streams from the shader. +unsigned int EffectGL::GetStreamCount() const { + return streams_.size(); +} + // Gets a handle to the selected parameter, and wraps it into an // EffectParamGL if successful. EffectParamGL *EffectGL::CreateParam(unsigned int index) { - if (index < low_level_params_.size()) return NULL; + if (index >= GetParamCount()) + return NULL; return EffectParamGL::Create(this, index); } +// Provided enough room is available in the buffer, fills the Desc structure, +// appending name and semantic if any. +bool EffectGL::GetStreamDesc(unsigned int index, + unsigned int size, + void *data) { + using effect_stream::Desc; + if (size < sizeof(Desc) || index >= streams_.size()) // NOLINT + return false; + + Desc *desc = static_cast<Desc *>(data); + *desc = streams_[index]; + return true; +} + // Gets a handle to the selected parameter, and wraps it into an // EffectParamGL if successful. EffectParamGL *EffectGL::CreateParamByName(const char *name) { int index = GetLowLevelParamIndexByName(name); if (index < 0) return NULL; - EffectParamGL::Create(this, index); + return EffectParamGL::Create(this, index); } BufferSyncInterface::ParseError GAPIGL::CreateEffect(ResourceID id, @@ -609,6 +803,28 @@ BufferSyncInterface::ParseError GAPIGL::GetParamDesc(ResourceID id, BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } +BufferSyncInterface::ParseError GAPIGL::GetStreamCount( + ResourceID id, + unsigned int size, + void *data) { + EffectGL *effect = effects_.Get(id); + if (!effect || size < sizeof(Uint32)) // NOLINT + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + *static_cast<Uint32 *>(data) = effect->GetStreamCount(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIGL::GetStreamDesc(ResourceID id, + unsigned int index, + unsigned int size, + void *data) { + EffectGL *effect = effects_.Get(id); + if (!effect) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return effect->GetStreamDesc(index, size, data) ? + BufferSyncInterface::PARSE_NO_ERROR : + BufferSyncInterface::PARSE_INVALID_ARGUMENTS; +} + // If the current effect is valid, call End on it, and tag for revalidation. void GAPIGL::DirtyEffect() { if (validate_effect_) return; diff --git a/o3d/command_buffer/service/cross/gl/effect_gl.h b/o3d/command_buffer/service/cross/gl/effect_gl.h index fc29bf3..cd81727 100644 --- a/o3d/command_buffer/service/cross/gl/effect_gl.h +++ b/o3d/command_buffer/service/cross/gl/effect_gl.h @@ -35,7 +35,10 @@ #ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_EFFECT_GL_H_ #define O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_EFFECT_GL_H_ +#include <Cg/cg.h> +#include <Cg/cgGL.h> #include <vector> + #include "command_buffer/common/cross/gapi_interface.h" #include "command_buffer/service/cross/resource.h" #include "command_buffer/service/cross/gl/gl_utils.h" @@ -95,9 +98,15 @@ class EffectGL : public Effect { // Gets the number of parameters in the effect. unsigned int GetParamCount() const; + // Gets the number of streams in the effect. + unsigned int GetStreamCount() const; + // Creates an effect parameter with the specified index. EffectParamGL *CreateParam(unsigned int index); + // Gets the stream data with the specified index. + bool GetStreamDesc(unsigned int index, unsigned int size, void *data); + // Creates an effect parameter of the specified name. EffectParamGL *CreateParamByName(const char *name); @@ -106,10 +115,12 @@ class EffectGL : public Effect { const char *name; CGparameter vp_param; CGparameter fp_param; - ResourceID sampler_id; + int num_elements; + std::vector<ResourceID> sampler_ids; }; typedef std::vector<LowLevelParam> LowLevelParamList; - typedef std::vector<EffectParamGL *> ParamResourceList; + typedef std::vector<EffectParamGL *> ParamList; + typedef std::vector<effect_stream::Desc> StreamList; static CGparameter GetEitherCgParameter( const LowLevelParam &low_level_param) { @@ -118,7 +129,8 @@ class EffectGL : public Effect { } int GetLowLevelParamIndexByName(const char *name); - void AddLowLevelParams(CGparameter cg_param, bool vp); + void AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp); + void AddStreams(CGprogram prog, CGenum name_space); // Creates the low level structures. void Initialize(); @@ -131,11 +143,13 @@ class EffectGL : public Effect { CGprogram vertex_program_; CGprogram fragment_program_; - // List of all the Param resources created. - ParamResourceList resource_params_; + // List of all the Params created. + ParamList params_; + StreamList streams_; // List of all the Cg parameters present in either the vertex program or the // fragment program. LowLevelParamList low_level_params_; + // List of the indices of the low level params that are samplers. std::vector<unsigned int> sampler_params_; bool update_samplers_; diff --git a/o3d/command_buffer/service/cross/gl/gapi_gl.cc b/o3d/command_buffer/service/cross/gl/gapi_gl.cc index a09375a..9f3873f 100644 --- a/o3d/command_buffer/service/cross/gl/gapi_gl.cc +++ b/o3d/command_buffer/service/cross/gl/gapi_gl.cc @@ -33,7 +33,6 @@ // This file implements the GAPIGL class. #include <build/build_config.h> -#include "command_buffer/service/cross/gl/gl_utils.h" #include "command_buffer/service/cross/gl/gapi_gl.h" #ifdef OS_LINUX @@ -47,6 +46,7 @@ GAPIGL::GAPIGL() #ifdef OS_LINUX : window_(NULL), #endif + : anti_aliased_(false), cg_context_(NULL), current_vertex_struct_(kInvalidResource), validate_streams_(true), @@ -60,41 +60,305 @@ GAPIGL::~GAPIGL() { } bool GAPIGL::Initialize() { -#ifdef OS_LINUX + if (!InitPlatformSpecific()) + return false; + if (!InitCommon()) + return false; + CHECK_GL_ERROR(); + return true; +} + +#if defined(OS_WIN) +static const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { + sizeof(kPixelFormatDescriptor), // Size of structure. + 1, // Default version. + PFD_DRAW_TO_WINDOW | // Window drawing support. + PFD_SUPPORT_OPENGL | // OpenGL support. + PFD_DOUBLEBUFFER, // Double buffering support (not stereo). + PFD_TYPE_RGBA, // RGBA color mode (not indexed). + 24, // 24 bit color mode. + 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. + 8, 0, // 8 bit alpha + 0, // No accumulation buffer. + 0, 0, 0, 0, // Ignore accumulation bits. + 24, // 24 bit z-buffer size. + 8, // 8-bit stencil buffer. + 0, // No aux buffer. + PFD_MAIN_PLANE, // Main drawing plane (not overlay). + 0, // Reserved. + 0, 0, 0, // Layer masks ignored. +}; + +LRESULT CALLBACK IntermediateWindowProc(HWND window, + UINT message, + WPARAM w_param, + LPARAM l_param) { + return ::DefWindowProc(window, message, w_param, l_param); +} + +// Helper routine that returns the highest quality pixel format supported on +// the current platform. Returns true upon success. +static bool GetWindowsPixelFormat(HWND window, + bool anti_aliased, + int* pixel_format) { + // We must initialize a GL context before we can determine the multi-sampling + // supported on the current hardware, so we create an intermediate window + // and context here. + HINSTANCE module_handle; + if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + reinterpret_cast<wchar_t*>(IntermediateWindowProc), + &module_handle)) { + return false; + } + + WNDCLASS intermediate_class; + intermediate_class.style = CS_HREDRAW | CS_VREDRAW; + intermediate_class.lpfnWndProc = IntermediateWindowProc; + intermediate_class.cbClsExtra = 0; + intermediate_class.cbWndExtra = 0; + intermediate_class.hInstance = module_handle; + intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); + intermediate_class.hbrBackground = NULL; + intermediate_class.lpszMenuName = NULL; + intermediate_class.lpszClassName = L"Intermediate GL Window"; + + ATOM class_registration = ::RegisterClass(&intermediate_class); + if (!class_registration) { + return false; + } + + HWND intermediate_window = ::CreateWindow( + reinterpret_cast<wchar_t*>(class_registration), + L"", + WS_OVERLAPPEDWINDOW, + 0, 0, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, + NULL, + NULL, + NULL); + + if (!intermediate_window) { + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + HDC intermediate_dc = ::GetDC(intermediate_window); + int format_index = ::ChoosePixelFormat(intermediate_dc, + &kPixelFormatDescriptor); + if (format_index == 0) { + DLOG(ERROR) << "Unable to get the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + if (!::SetPixelFormat(intermediate_dc, format_index, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + // Store the pixel format without multisampling. + *pixel_format = format_index; + HGLRC gl_context = ::wglCreateContext(intermediate_dc); + if (::wglMakeCurrent(intermediate_dc, gl_context)) { + // GL context was successfully created and applied to the window's DC. + // Startup GLEW, the GL extensions wrangler. + GLenum glew_error = ::glewInit(); + if (glew_error == GLEW_OK) { + DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); + } else { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + // If the multi-sample extensions are present, query the api to determine + // the pixel format. + if (anti_aliased && WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { + int pixel_attributes[] = { + WGL_SAMPLES_ARB, 4, + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB, 24, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + 0, 0}; + + float pixel_attributes_f[] = {0, 0}; + int msaa_pixel_format; + unsigned int num_formats; + + // Query for the highest sampling rate supported, starting at 4x. + static const int kSampleCount[] = {4, 2}; + static const int kNumSamples = 2; + for (int sample = 0; sample < kNumSamples; ++sample) { + pixel_attributes[1] = kSampleCount[sample]; + if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, + pixel_attributes, + pixel_attributes_f, + 1, + &msaa_pixel_format, + &num_formats)) { + *pixel_format = msaa_pixel_format; + break; + } + } + } + } + + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return true; +} +#endif + +bool GAPIGL::InitPlatformSpecific() { +#if defined(OS_WIN) + device_context_ = ::GetDC(hwnd_); + + int pixel_format; + + if (!GetWindowsPixelFormat(hwnd_, + anti_aliased(), + &pixel_format)) { + DLOG(ERROR) << "Unable to determine optimal pixel format for GL context."; + return false; + } + + if (!::SetPixelFormat(device_context_, pixel_format, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + return false; + } + + gl_context_ = ::wglCreateContext(device_context_); + if (!gl_context_) { + DLOG(ERROR) << "Failed to create GL context."; + return false; + } + + if (!::wglMakeCurrent(device_context_, gl_context_)) { + DLOG(ERROR) << "Unable to make gl context current."; + return false; + } +#elif defined(OS_LINUX) DCHECK(window_); if (!window_->Initialize()) return false; if (!window_->MakeCurrent()) return false; - InitCommon(); - CHECK_GL_ERROR(); - return true; -#else - return false; #endif + + return true; } -void GAPIGL::InitCommon() { - cg_context_ = cgCreateContext(); - // Set up all Cg State Assignments for OpenGL. - cgGLRegisterStates(cg_context_); - cgGLSetDebugMode(CG_FALSE); - // Enable the profiles we use. - cgGLEnableProfile(CG_PROFILE_ARBVP1); - cgGLEnableProfile(CG_PROFILE_ARBFP1); +bool GAPIGL::InitCommon() { + if (!InitGlew()) + return false; + InitCG(); + // Initialize global GL settings. // Tell GL that texture buffers can be single-byte aligned. glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - // Get the initial viewport (set to the window size) to set up the helper // constant. GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); SetViewport(viewport[0], viewport[1], viewport[2], viewport[3], 0.f, 1.f); CHECK_GL_ERROR(); + return true; +} + +void GAPIGL::InitCG() { + cg_context_ = cgCreateContext(); + // Set up all Cg State Assignments for OpenGL. + cgGLRegisterStates(cg_context_); + cgGLSetDebugMode(CG_FALSE); + // Enable the profiles we use. + cgGLEnableProfile(CG_PROFILE_ARBVP1); + cgGLEnableProfile(CG_PROFILE_ARBFP1); +} + +bool GAPIGL::InitGlew() { + DLOG(INFO) << "Initializing GL and GLEW for GAPI."; + + GLenum glew_error = glewInit(); + if (glew_error != GLEW_OK) { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + return false; + } + + // Check to see that we can use the OpenGL vertex attribute APIs + // TODO(petersont): Return false if this check fails, but because some + // Intel hardware does not support OpenGL 2.0, yet does support all of the + // extensions we require, we only log an error. A future CL should change + // this check to ensure that all of the extension strings we require are + // present. + if (!GLEW_VERSION_2_0) { + DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality."; + return false; + } + + bool extensions_found = true; + if (!GLEW_ARB_vertex_buffer_object) { + // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using + // indirect rendering (e.g. remote X), but it is actually lying. The + // ARB_vertex_buffer_object functions silently no-op (!) when using + // indirect rendering, leading to crashes. Fortunately, in that case, the + // driver claims to not support ARB_vertex_buffer_object, so fail in that + // case. + DLOG(ERROR) << "GL drivers do not support vertex buffer objects."; + extensions_found = false; + } + if (!GLEW_EXT_framebuffer_object) { + DLOG(ERROR) << "GL drivers do not support framebuffer objects."; + extensions_found = false; + } + // Check for necessary extensions + if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) { + DLOG(ERROR) << "Two sided stencil extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) { + DLOG(ERROR) <<"Separate blend func extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) { + DLOG(ERROR) << "Separate blend function extension missing."; + extensions_found = false; + } + if (!extensions_found) + return false; + + return true; } void GAPIGL::Destroy() { @@ -117,10 +381,15 @@ void GAPIGL::BeginFrame() { } void GAPIGL::EndFrame() { +#ifdef OS_WIN + ::SwapBuffers(device_context_); +#endif + #ifdef OS_LINUX DCHECK(window_); window_->SwapBuffers(); #endif + CHECK_GL_ERROR(); } diff --git a/o3d/command_buffer/service/cross/gl/gapi_gl.h b/o3d/command_buffer/service/cross/gl/gapi_gl.h index 8d71800..1331e33 100644 --- a/o3d/command_buffer/service/cross/gl/gapi_gl.h +++ b/o3d/command_buffer/service/cross/gl/gapi_gl.h @@ -67,6 +67,12 @@ class GAPIGL : public GAPIInterface { // true if successful. virtual bool Initialize(); + // Initailizes Cg. + void InitCG(); + + // Helper function for Initailize that inits just glew. + bool InitGlew(); + // Destroys the graphics context. virtual void Destroy(); @@ -203,6 +209,17 @@ class GAPIGL : public GAPIInterface { unsigned int size, void *data); + // Implements the GetStreamCount function for GL. + virtual ParseError GetStreamCount(ResourceID id, + unsigned int size, + void *data); + + // Implements the GetStreamDesc function for GL. + virtual ParseError GetStreamDesc(ResourceID id, + unsigned int index, + unsigned int size, + void *data); + // Implements the CreateTexture2D function for GL. virtual ParseError CreateTexture2D(ResourceID id, unsigned int width, @@ -353,6 +370,9 @@ class GAPIGL : public GAPIInterface { SamplerGL *GetSampler(ResourceID id) { return samplers_.Get(id); } + void set_anti_aliased(bool anti_aliased) { anti_aliased_ = anti_aliased; } + + bool anti_aliased() const { return anti_aliased_; } CGcontext cg_context() const { return cg_context_; } @@ -361,18 +381,26 @@ class GAPIGL : public GAPIInterface { // and requires ValidateEffect() to be called before further draws occur. void DirtyEffect(); private: - void InitCommon(); + bool InitPlatformSpecific(); + bool InitCommon(); // Validates the current vertex struct to GL, setting the vertex attributes. bool ValidateStreams(); // Validates the current effect to GL. This sets the vertex and fragment // programs, and updates parameters if needed. bool ValidateEffect(); -#ifdef OS_LINUX +#if defined(OS_LINUX) XWindowWrapper *window_; +#elif defined(OS_WIN) + // Handle to the GL device. + HWND hwnd_; + HDC device_context_; + HGLRC gl_context_; #endif + CGcontext cg_context_; + bool anti_aliased_; ResourceID current_vertex_struct_; bool validate_streams_; unsigned int max_vertices_; diff --git a/o3d/command_buffer/service/cross/gl/geometry_gl.cc b/o3d/command_buffer/service/cross/gl/geometry_gl.cc index 2dd8758..be5bf1a1 100644 --- a/o3d/command_buffer/service/cross/gl/geometry_gl.cc +++ b/o3d/command_buffer/service/cross/gl/geometry_gl.cc @@ -160,8 +160,12 @@ void VertexStructGL::SetInput(unsigned int input_index, namespace { -inline const GLvoid *OffsetToPtr(GLintptr offset) { - return static_cast<char *>(NULL) + offset; +inline ptrdiff_t OffsetToPtrDiff(unsigned int offset) { + return static_cast<ptrdiff_t>(offset); +} + +inline void* OffsetToPtr(ptrdiff_t offset) { + return reinterpret_cast<void*>(offset); } } // anonymous namespace @@ -189,7 +193,8 @@ unsigned int VertexStructGL::SetStreams(GAPIGL *gapi) { DCHECK_NE(vertex_buffer->gl_buffer(), 0); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer->gl_buffer()); glVertexAttribPointer(i, attrib.size, attrib.type, attrib.normalized, - attrib.stride, OffsetToPtr(attrib.offset)); + attrib.stride, + OffsetToPtr(attrib.offset)); max_vertices = std::min(max_vertices, vertex_buffer->size() / attrib.stride); } @@ -295,7 +300,7 @@ void VertexStructGL::Compile() { ExtractSizeTypeNormalized(element.type, &attrib.size, &attrib.type, &attrib.normalized); attrib.stride = element.stride; - attrib.offset = element.offset; + attrib.offset = OffsetToPtrDiff(element.offset); } dirty_ = false; } @@ -347,7 +352,7 @@ BufferSyncInterface::ParseError GAPIGL::CreateIndexBuffer(ResourceID id, } BufferSyncInterface::ParseError GAPIGL::DestroyIndexBuffer(ResourceID id) { - return vertex_buffers_.Destroy(id) ? + return index_buffers_.Destroy(id) ? BufferSyncInterface::PARSE_NO_ERROR : BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } diff --git a/o3d/command_buffer/service/cross/gl/gl_utils.h b/o3d/command_buffer/service/cross/gl/gl_utils.h index b41a4cf..6b160d4b 100644 --- a/o3d/command_buffer/service/cross/gl/gl_utils.h +++ b/o3d/command_buffer/service/cross/gl/gl_utils.h @@ -30,24 +30,15 @@ */ -// This file includes all the necessary GL/Cg headers and implement some useful +// This file includes all the necessary GL/Cg headers and implements some useful // utilities. #ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_GL_UTILS_H_ #define O3D_COMMAND_BUFFER_SERVICE_CROSS_GL_GL_UTILS_H_ #include <build/build_config.h> + #define GL_GLEXT_PROTOTYPES -#if defined(OS_WIN) -#include <GL/gl.h> -#elif defined(OS_MACOSX) -#include <OpenGL/OpenGL.h> -#include <AGL/agl.h> -#elif defined(OS_LINUX) -#include <GL/gl.h> -#endif // defined(PLATFORM) -#include <Cg/cg.h> -#include <Cg/cgGL.h> // Define this for extra GL error debugging (slower). // #define GL_ERROR_DEBUGGING diff --git a/o3d/command_buffer/service/cross/plugin.cc b/o3d/command_buffer/service/cross/plugin.cc index 352a084..1a20dd5 100644 --- a/o3d/command_buffer/service/cross/plugin.cc +++ b/o3d/command_buffer/service/cross/plugin.cc @@ -155,7 +155,7 @@ NPError Plugin::SetWindow(NPWindow *window) { void Plugin::Create(nacl::HtpHandle handle) { if (gapi_.get()) return; handle_ = handle; -#ifdef OS_WIN +#ifdef CB_SERVICE_D3D9 if (!hwnd_) return; GAPID3D9 *gapi_d3d = new GAPID3D9; gapi_d3d->set_hwnd(hwnd_); diff --git a/o3d/command_buffer/service/cross/precompile.cc b/o3d/command_buffer/service/cross/precompile.cc new file mode 100644 index 0000000..97064b4 --- /dev/null +++ b/o3d/command_buffer/service/cross/precompile.cc @@ -0,0 +1,33 @@ +/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "command_buffer/service/cross/precompile.h"
diff --git a/o3d/command_buffer/service/cross/precompile.h b/o3d/command_buffer/service/cross/precompile.h new file mode 100644 index 0000000..cb9e81a --- /dev/null +++ b/o3d/command_buffer/service/cross/precompile.h @@ -0,0 +1,62 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains includes for common headers used by command buffer server +// files. It is used for pre-compiled header support. + +#ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H__ +#define O3D_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H__ + +#include <build/build_config.h> + +#if defined(OS_WIN) +#include <windows.h> +#endif + +#if defined(CB_SERVICE_D3D9) +#include <d3d9.h> +#include <d3dx9.h> +#endif // defined(CB_SERVICE_D3D9) + +#if defined(CB_SERVICE_GL) +#include <GL/glew.h> +#include <GL/wglew.h> +#include <Cg/cg.h> +#include <Cg/cgGL.h> +#endif // defined(CB_SERVICE_GL) + +#include <assert.h> +#include <algorithm> +#include <map> +#include <vector> + +#endif // O3D_CORE_CROSS_PRECOMPILE_H__ diff --git a/o3d/command_buffer/service/win/big_test_main.cc b/o3d/command_buffer/service/win/big_test_main.cc index 8a21b72..a88dc2d 100644 --- a/o3d/command_buffer/service/win/big_test_main.cc +++ b/o3d/command_buffer/service/win/big_test_main.cc @@ -33,7 +33,13 @@ #include <windows.h> #include <Shellapi.h> #include "command_buffer/service/cross/big_test_helpers.h" + +#if defined(CB_SERVICE_D3D9) #include "command_buffer/service/win/d3d9/gapi_d3d9.h" +#elif defined(CB_SERVICE_GL) +#include "command_buffer/service/cross/gl/gapi_gl.h" +#endif + #include "core/cross/types.h" namespace o3d { @@ -101,7 +107,12 @@ bool ProcessSystemMessages() { using o3d::String; using o3d::command_buffer::g_program_path; using o3d::command_buffer::g_gapi; + +#if defined(CB_SERVICE_D3D9) using o3d::command_buffer::GAPID3D9; +#elif defined(CB_SERVICE_GL) +using o3d::command_buffer::GAPIGL; +#endif LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, @@ -133,9 +144,14 @@ int main(int argc, char *argv[]) { 300, GetDesktopWindow(), NULL, wc.hInstance, NULL); UpdateWindow(hWnd); - GAPID3D9 d3d9_gapi; - d3d9_gapi.set_hwnd(hWnd); - g_gapi = &d3d9_gapi; +#if defined(CB_SERVICE_D3D9) + GAPID3D9 gapi; +#elif defined(CB_SERVICE_GL) + GAPIGL gapi; +#endif + + gapi.set_hwnd(hWnd); + g_gapi = &gapi; wchar_t program_filename[512]; GetModuleFileName(NULL, program_filename, sizeof(program_filename)); diff --git a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc index 622f363..76da265 100644 --- a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc +++ b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc @@ -441,6 +441,7 @@ bool EffectParamD3D9::GetDesc(unsigned int size, void *data) { desc->data_size = GetDataSize(data_type()); desc->name_offset = 0; desc->name_size = name_size; + desc->num_elements = d3d_desc.Elements; desc->semantic_offset = 0; desc->semantic_size = semantic_size; unsigned int current_offset = sizeof(Desc); @@ -625,7 +626,7 @@ BufferSyncInterface::ParseError GAPID3D9::GetParamDesc( BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } -// Gets the stream count from the effect and store it in the memory buffer. +// Gets the stream count from the effect and stores it in the memory buffer. BufferSyncInterface::ParseError GAPID3D9::GetStreamCount( ResourceID id, unsigned int size, |