summaryrefslogtreecommitdiffstats
path: root/o3d/command_buffer
diff options
context:
space:
mode:
authorpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 02:39:33 +0000
committerpetersont@google.com <petersont@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 02:39:33 +0000
commite73d4f7b1f150436dae5d589fd73c8d17c2dcb56 (patch)
treeabdc8f4fba62512c716f14b67badd7993c0394fe /o3d/command_buffer
parenta4369599f7e9c15c66bcf66cc1c9bd158666eea4 (diff)
downloadchromium_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.cc1
-rw-r--r--o3d/command_buffer/client/cross/effect_helper.h2
-rw-r--r--o3d/command_buffer/common/cross/resource.h11
-rw-r--r--o3d/command_buffer/service/build.scons66
-rw-r--r--o3d/command_buffer/service/cross/gl/effect_gl.cc292
-rw-r--r--o3d/command_buffer/service/cross/gl/effect_gl.h24
-rw-r--r--o3d/command_buffer/service/cross/gl/gapi_gl.cc301
-rw-r--r--o3d/command_buffer/service/cross/gl/gapi_gl.h32
-rw-r--r--o3d/command_buffer/service/cross/gl/geometry_gl.cc15
-rw-r--r--o3d/command_buffer/service/cross/gl/gl_utils.h13
-rw-r--r--o3d/command_buffer/service/cross/plugin.cc2
-rw-r--r--o3d/command_buffer/service/cross/precompile.cc33
-rw-r--r--o3d/command_buffer/service/cross/precompile.h62
-rw-r--r--o3d/command_buffer/service/win/big_test_main.cc22
-rw-r--r--o3d/command_buffer/service/win/d3d9/effect_d3d9.cc3
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,