summaryrefslogtreecommitdiffstats
path: root/o3d/gpu/command_buffer/service/effect_gl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/gpu/command_buffer/service/effect_gl.cc')
-rw-r--r--o3d/gpu/command_buffer/service/effect_gl.cc852
1 files changed, 0 insertions, 852 deletions
diff --git a/o3d/gpu/command_buffer/service/effect_gl.cc b/o3d/gpu/command_buffer/service/effect_gl.cc
deleted file mode 100644
index b8f9601..0000000
--- a/o3d/gpu/command_buffer/service/effect_gl.cc
+++ /dev/null
@@ -1,852 +0,0 @@
-/*
- * 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 the implementation of the EffectParamGL and EffectGL
-// classes, as well as the effect-related GAPI functions on GL.
-
-#include "gpu/command_buffer/service/precompile.h"
-
-#include <map>
-
-#include "base/cross/std_functional.h"
-#include "gpu/command_buffer/service/effect_gl.h"
-#include "gpu/command_buffer/service/gapi_gl.h"
-#include "gpu/command_buffer/service/effect_utils.h"
-
-namespace command_buffer {
-namespace o3d {
-
-EffectParamGL::EffectParamGL(effect_param::DataType data_type,
- EffectGL *effect,
- unsigned int param_index)
- : EffectParam(data_type),
- effect_(effect),
- low_level_param_index_(param_index) {
- DCHECK(effect_);
- effect_->LinkParam(this);
-}
-
-EffectParamGL::~EffectParamGL() {
- if (effect_)
- effect_->UnlinkParam(this);
-}
-
-static effect_param::DataType CgTypeToCBType(CGtype cg_type) {
- switch (cg_type) {
- case CG_FLOAT:
- case CG_FLOAT1:
- return effect_param::kFloat1;
- case CG_FLOAT2:
- return effect_param::kFloat2;
- case CG_FLOAT3:
- return effect_param::kFloat3;
- case CG_FLOAT4:
- return effect_param::kFloat4;
- case CG_INT:
- case CG_INT1:
- return effect_param::kInt;
- case CG_BOOL:
- case CG_BOOL1:
- return effect_param::kBool;
- case CG_FLOAT4x4:
- return effect_param::kMatrix4;
- case CG_SAMPLER:
- case CG_SAMPLER1D:
- case CG_SAMPLER2D:
- case CG_SAMPLER3D:
- case CG_SAMPLERCUBE:
- return effect_param::kSampler;
- case CG_TEXTURE:
- return effect_param::kTexture;
- default : {
- DLOG(INFO) << "Cannot convert CGtype "
- << cgGetTypeString(cg_type)
- << " to a Param type.";
- return effect_param::kUnknown;
- }
- }
-}
-
-EffectParamGL *EffectParamGL::Create(EffectGL *effect,
- unsigned int index) {
- DCHECK(effect);
- const EffectGL::LowLevelParam &low_level_param =
- effect->low_level_params_[index];
- 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::kUnknown)
- return NULL;
- return new EffectParamGL(type, effect, index);
-}
-
-// Fills the Desc structure, appending name and semantic if any, and if enough
-// room is available in the buffer.
-bool EffectParamGL::GetDesc(unsigned int size, void *data) {
- using effect_param::Desc;
- if (size < sizeof(Desc)) // NOLINT
- return false;
- if (!effect_)
- return false;
- const EffectGL::LowLevelParam &low_level_param =
- effect_->low_level_params_[low_level_param_index_];
- 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 ?
- static_cast<unsigned int>(strlen(semantic)) + 1 : 0;
- unsigned int total_size = sizeof(Desc) + name_size + semantic_size; // NOLINT
-
- Desc *desc = static_cast<Desc *>(data);
- memset(desc, 0, sizeof(*desc));
- desc->size = total_size;
- desc->data_type = data_type();
- desc->data_size = GetDataSize(data_type());
- 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) {
- desc->name_offset = current_offset;
- memcpy(static_cast<char *>(data) + current_offset, name, name_size);
- current_offset += name_size;
- }
- if (semantic && current_offset + semantic_size <= size) {
- desc->semantic_offset = current_offset;
- memcpy(static_cast<char *>(data) + current_offset, semantic, semantic_size);
- current_offset += semantic_size;
- }
- return true;
-}
-
-// Sets the data into the Cg effect parameter, using the appropriate Cg call.
-bool EffectParamGL::SetData(GAPIGL *gapi,
- unsigned int size,
- const void * data) {
- if (!effect_)
- return false;
-
- 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();
- if (size < effect_param::GetDataSize(type))
- return false;
-
- switch (type) {
- case effect_param::kFloat1:
- if (vp_param)
- cgSetParameter1f(vp_param, *static_cast<const float *>(data));
- if (fp_param)
- cgSetParameter1f(fp_param, *static_cast<const float *>(data));
- break;
- case effect_param::kFloat2:
- if (vp_param)
- cgSetParameter2fv(vp_param, static_cast<const float *>(data));
- if (fp_param)
- cgSetParameter2fv(fp_param, static_cast<const float *>(data));
- break;
- case effect_param::kFloat3:
- if (vp_param)
- cgSetParameter3fv(vp_param, static_cast<const float *>(data));
- if (fp_param)
- cgSetParameter3fv(fp_param, static_cast<const float *>(data));
- break;
- case effect_param::kFloat4:
- if (vp_param)
- cgSetParameter4fv(vp_param, static_cast<const float *>(data));
- if (fp_param)
- cgSetParameter4fv(fp_param, static_cast<const float *>(data));
- break;
- case effect_param::kMatrix4:
- if (vp_param)
- cgSetMatrixParameterfr(vp_param, static_cast<const float *>(data));
- if (fp_param)
- cgSetMatrixParameterfr(fp_param, static_cast<const float *>(data));
- break;
- case effect_param::kInt:
- if (vp_param) cgSetParameter1i(vp_param, *static_cast<const int *>(data));
- if (fp_param) cgSetParameter1i(fp_param, *static_cast<const int *>(data));
- break;
- case effect_param::kBool: {
- int bool_value = *static_cast<const bool *>(data)?1:0;
- if (vp_param) cgSetParameter1i(vp_param, bool_value);
- if (fp_param) cgSetParameter1i(fp_param, bool_value);
- break;
- }
- case effect_param::kSampler: {
- DCHECK_GE(low_level_param.sampler_ids.size(), 1U);
- low_level_param.sampler_ids[0] = *static_cast<const ResourceId *>(data);
- if (effect_ == gapi->current_effect()) {
- gapi->DirtyEffect();
- }
- break;
- }
- default:
- DLOG(ERROR) << "Invalid parameter type.";
- return false;
- }
- return true;
-}
-EffectGL::EffectGL(CGprogram vertex_program,
- CGprogram fragment_program)
- : vertex_program_(vertex_program),
- fragment_program_(fragment_program),
- update_samplers_(true) {
-}
-
-EffectGL::~EffectGL() {
- for (ParamList::iterator it = params_.begin();
- it != params_.end(); ++it) {
- (*it)->ResetEffect();
- }
-}
-
-void EffectGL::LinkParam(EffectParamGL *param) {
- params_.push_back(param);
-}
-
-void EffectGL::UnlinkParam(EffectParamGL *param) {
- std::remove(params_.begin(), params_.end(), param);
-}
-
-// Rewrites vertex program assembly code to match GL semantics for clipping.
-// This parses the source, breaking it down into pieces:
-// - declaration ("!!ARBvp1.0")
-// - comments (that contain the parameter information)
-// - instructions
-// - "END" token.
-// Then it rewrites the instructions so that 'result.position' doesn't get
-// written directly, instead it is written to a temporary variable. Then a
-// transformation is done on that variable before outputing to
-// 'result.position':
-// - offset x an y by half a pixel (times w).
-// - remap z from [0..w] to [-w..w].
-//
-// Note that for the 1/2 pixel offset, we need a parameter that depends on the
-// current viewport. This is done through 'program.env[0]' which is shared
-// across all programs (so we only have to update it once when we change the
-// viewport), because Cg won't use them currently (it uses 'program.local'
-// instead).
-static bool RewriteVertexProgramSource(String *source) {
- String::size_type pos = source->find('\n');
- if (pos == String::npos) {
- DLOG(ERROR) << "could not find program declaration";
- return false;
- }
- String decl(*source, 0, pos + 1);
- String::size_type start_comments = pos + 1;
- // skip the comments that contain the parameters etc.
- for (; pos < source->size(); pos = source->find('\n', pos)) {
- ++pos;
- if (pos >= source->size())
- break;
- if ((*source)[pos] != '#')
- break;
- }
- if (pos >= source->size()) {
- // we only found comments.
- return false;
- }
- String comments(*source, start_comments, pos - start_comments);
-
- String::size_type end_token = source->find("\nEND", pos + 1);
- if (end_token == String::npos) {
- DLOG(ERROR) << "Compiled shader doesn't have an END token";
- return false;
- }
- String instructions(*source, pos, end_token + 1 - pos);
-
- // Replace accesses to 'result.position' by accesses to our temp variable
- // '$O3D_HPOS'.
- // '$' is a valid symbol for identifiers, but Cg doesn't seem to be using
- // it, so we can use it to ensure we don't have name conflicts.
- static const char kOutPositionRegister[] = "result.position";
- for (String::size_type i = instructions.find(kOutPositionRegister);
- i < String::npos; i = instructions.find(kOutPositionRegister, i)) {
- instructions.replace(i, strlen(kOutPositionRegister), "$O3D_HPOS");
- }
-
- *source = decl +
- comments +
- // .x = 1/viewport.width; .y = 1/viewport.height; .z = 2.0;
- "PARAM $O3D_HELPER = program.env[0];\n"
- "TEMP $O3D_HPOS;\n" +
- instructions +
- // hpos.x <- hpos.x + hpos.w / viewport.width;
- // hpos.y <- hpos.y - hpos.w / viewport.height;
- "MAD $O3D_HPOS.xy, $O3D_HELPER.xyyy, $O3D_HPOS.w, $O3D_HPOS.xyyy;\n"
- // hpos.z <- hpos.z * 2 - hpos.w
- "MAD $O3D_HPOS.z, $O3D_HPOS.z, $O3D_HELPER.z, -$O3D_HPOS.w;\n"
- "MOV result.position, $O3D_HPOS;\n"
- "END\n";
- return true;
-}
-
-EffectGL *EffectGL::Create(GAPIGL *gapi,
- const String& effect_code,
- const String& vertex_program_entry,
- const String& fragment_program_entry) {
- CGcontext context = gapi->cg_context();
- // Compile the original vertex program once, to get the ARBVP1 assembly code.
- CGprogram original_vp = cgCreateProgram(
- context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBVP1,
- vertex_program_entry.c_str(), NULL);
- const char* listing = cgGetLastListing(context);
- if (original_vp == NULL) {
- DLOG(ERROR) << "Effect Compile Error: " << cgGetErrorString(cgGetError())
- << " : " << listing;
- return NULL;
- }
-
- if (listing && listing[0] != 0) {
- DLOG(WARNING) << "Effect Compile Warnings: " << listing;
- }
-
- String vp_assembly = cgGetProgramString(original_vp, CG_COMPILED_PROGRAM);
- cgDestroyProgram(original_vp);
- if (!RewriteVertexProgramSource(&vp_assembly)) {
- return NULL;
- }
- CGprogram vertex_program = cgCreateProgram(
- context, CG_OBJECT, vp_assembly.c_str(), CG_PROFILE_ARBVP1,
- vertex_program_entry.c_str(), NULL);
- listing = cgGetLastListing(context);
- if (vertex_program == NULL) {
- DLOG(ERROR) << "Effect post-rewrite Compile Error: "
- << cgGetErrorString(cgGetError()) << " : " << listing;
- return false;
- }
-
- if (listing && listing[0] != 0) {
- DLOG(WARNING) << "Effect post-rewrite compile warnings: " << listing;
- }
-
- CHECK_GL_ERROR();
-
- // If the program rewrite introduced some syntax or semantic errors, we won't
- // know it until we load the program (through a GL error).
- // So flush all GL errors first...
- do {} while (glGetError() != GL_NO_ERROR);
-
- // ... Then load the program ...
- cgGLLoadProgram(vertex_program);
-
- // ... And check for GL errors.
- if (glGetError() != GL_NO_ERROR) {
- DLOG(ERROR) << "Effect post-rewrite GL Error: "
- << glGetString(GL_PROGRAM_ERROR_STRING_ARB)
- << "\nSource: \n"
- << vp_assembly;
- return NULL;
- }
-
- CGprogram fragment_program = cgCreateProgram(
- context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBFP1,
- fragment_program_entry.c_str(), NULL);
- listing = cgGetLastListing(context);
- if (fragment_program == NULL) {
- DLOG(ERROR) << "Effect Compile Error: "
- << cgGetErrorString(cgGetError()) << " : "
- << listing;
- return NULL;
- }
-
- if (listing && listing[0] != 0) {
- DLOG(WARNING) << "Effect Compile Warnings: " << listing;
- }
-
- cgGLLoadProgram(fragment_program);
-
- // Also check for GL errors, in case Cg managed to compile, but generated a
- // bad program.
- if (glGetError() != GL_NO_ERROR) {
- DLOG(ERROR) << "Effect GL Error: "
- << glGetString(GL_PROGRAM_ERROR_STRING_ARB);
- return false;
- }
- EffectGL *effect = new EffectGL(vertex_program, fragment_program);
- effect->Initialize();
- return effect;
-}
-
-int EffectGL::GetLowLevelParamIndexByName(const char *name) {
- DCHECK(name);
- for (unsigned int index = 0; index < low_level_params_.size(); ++index) {
- if (!strcmp(name, low_level_params_[index].name)) {
- return index;
- }
- }
- return -1;
-}
-
-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;
- CGenum direction = cgGetParameterDirection(cg_param);
- if (direction != CG_IN)
- continue;
- const char *name = cgGetParameterName(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;
- param.name = name;
- param.vp_param = NULL;
- param.fp_param = NULL;
- param.num_elements = num_elements;
-
- index = low_level_params_.size();
- 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 {
- low_level_params_[index].fp_param = 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.
-// TODO(gman): remove this.
-SemanticMapElement semantic_map_array[] = {
- SemanticMapElement("POSITION",
- effect_stream::Desc(vertex_struct::kPosition, 0)),
- SemanticMapElement("ATTR0",
- effect_stream::Desc(vertex_struct::kPosition, 0)),
- SemanticMapElement("BLENDWEIGHT",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("ATTR1",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("NORMAL",
- effect_stream::Desc(vertex_struct::kNormal, 0)),
- SemanticMapElement("ATTR2",
- effect_stream::Desc(vertex_struct::kNormal, 0)),
- SemanticMapElement("COLOR0",
- effect_stream::Desc(vertex_struct::kColor, 0)),
- SemanticMapElement("DIFFUSE",
- effect_stream::Desc(vertex_struct::kColor, 0)),
- SemanticMapElement("ATTR3",
- effect_stream::Desc(vertex_struct::kColor, 0)),
- SemanticMapElement("COLOR1",
- effect_stream::Desc(vertex_struct::kColor, 1)),
- SemanticMapElement("SPECULAR",
- effect_stream::Desc(vertex_struct::kColor, 1)),
- SemanticMapElement("ATTR4",
- effect_stream::Desc(vertex_struct::kColor, 1)),
- SemanticMapElement("TESSFACTOR",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("FOGCOORD",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("ATTR5",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("PSIZE",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("ATTR6",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("BLENDINDICES",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("ATTR7",
- effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)),
- SemanticMapElement("TEXCOORD0",
- effect_stream::Desc(vertex_struct::kTexCoord, 0)),
- SemanticMapElement("ATTR8",
- effect_stream::Desc(vertex_struct::kTexCoord, 0)),
- SemanticMapElement("TEXCOORD1",
- effect_stream::Desc(vertex_struct::kTexCoord, 1)),
- SemanticMapElement("ATTR9",
- effect_stream::Desc(vertex_struct::kTexCoord, 1)),
- SemanticMapElement("TEXCOORD2",
- effect_stream::Desc(vertex_struct::kTexCoord, 2)),
- SemanticMapElement("ATTR10",
- effect_stream::Desc(vertex_struct::kTexCoord, 2)),
- SemanticMapElement("TEXCOORD3",
- effect_stream::Desc(vertex_struct::kTexCoord, 3)),
- SemanticMapElement("ATTR11",
- effect_stream::Desc(vertex_struct::kTexCoord, 3)),
- SemanticMapElement("TEXCOORD4",
- effect_stream::Desc(vertex_struct::kTexCoord, 4)),
- SemanticMapElement("ATTR12",
- effect_stream::Desc(vertex_struct::kTexCoord, 4)),
- SemanticMapElement("TEXCOORD5",
- effect_stream::Desc(vertex_struct::kTexCoord, 5)),
- SemanticMapElement("ATTR13",
- effect_stream::Desc(vertex_struct::kTexCoord, 5)),
- SemanticMapElement("TEXCOORD6",
- effect_stream::Desc(vertex_struct::kTexCoord, 6)),
- SemanticMapElement("TANGENT",
- effect_stream::Desc(vertex_struct::kTexCoord, 6)),
- SemanticMapElement("ATTR14",
- effect_stream::Desc(vertex_struct::kTexCoord, 7)),
- SemanticMapElement("TEXCOORD7",
- effect_stream::Desc(vertex_struct::kTexCoord, 7)),
- SemanticMapElement("BINORMAL",
- effect_stream::Desc(vertex_struct::kTexCoord, 8)),
- SemanticMapElement("ATTR15",
- effect_stream::Desc(vertex_struct::kTexCoord, 8))
-};
-
-static SemanticMap semantic_map(semantic_map_array,
- semantic_map_array +
- arraysize(semantic_map_array));
-
-void EffectGL::Initialize() {
- 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::kUnknownSemantic, 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];
- 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;
- }
- }
- }
- }
- // Second to enable/disable the sampler params.
- 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];
- 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;
-}
-
-// Terminates rendering with the effect, resetting all the appropriate states.
-void EffectGL::End(GAPIGL *gapi) {
-}
-
-// Gets the parameter count from the list.
-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 >= 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;
- return EffectParamGL::Create(this, index);
-}
-
-parse_error::ParseError GAPIGL::CreateEffect(ResourceId id,
- unsigned int size,
- const void *data) {
- if (id == current_effect_id_) DirtyEffect();
- // Even though Assign would Destroy the effect at id, we do it explicitly in
- // case the creation fails.
- effects_.Destroy(id);
- // Data is vp_main \0 fp_main \0 effect_text.
- String vertex_program_entry;
- String fragment_program_entry;
- String effect_code;
- if (!ParseEffectData(size, data,
- &vertex_program_entry,
- &fragment_program_entry,
- &effect_code)) {
- return parse_error::kParseInvalidArguments;
- }
- EffectGL * effect = EffectGL::Create(this, effect_code,
- vertex_program_entry,
- fragment_program_entry);
- if (!effect) return parse_error::kParseInvalidArguments;
- effects_.Assign(id, effect);
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::DestroyEffect(ResourceId id) {
- if (id == current_effect_id_) DirtyEffect();
- return effects_.Destroy(id) ?
- parse_error::kParseNoError :
- parse_error::kParseInvalidArguments;
-}
-
-parse_error::ParseError GAPIGL::SetEffect(ResourceId id) {
- DirtyEffect();
- current_effect_id_ = id;
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::GetParamCount(ResourceId id,
- unsigned int size,
- void *data) {
- EffectGL *effect = effects_.Get(id);
- if (!effect || size < sizeof(Uint32)) // NOLINT
- return parse_error::kParseInvalidArguments;
- *static_cast<Uint32 *>(data) = effect->GetParamCount();
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::CreateParam(ResourceId param_id,
- ResourceId effect_id,
- unsigned int index) {
- EffectGL *effect = effects_.Get(effect_id);
- if (!effect) return parse_error::kParseInvalidArguments;
- EffectParamGL *param = effect->CreateParam(index);
- if (!param) return parse_error::kParseInvalidArguments;
- effect_params_.Assign(param_id, param);
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::CreateParamByName(ResourceId param_id,
- ResourceId effect_id,
- unsigned int size,
- const void *name) {
- EffectGL *effect = effects_.Get(effect_id);
- if (!effect) return parse_error::kParseInvalidArguments;
- std::string string_name(static_cast<const char *>(name), size);
- EffectParamGL *param = effect->CreateParamByName(string_name.c_str());
- if (!param) return parse_error::kParseInvalidArguments;
- effect_params_.Assign(param_id, param);
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::DestroyParam(ResourceId id) {
- return effect_params_.Destroy(id) ?
- parse_error::kParseNoError :
- parse_error::kParseInvalidArguments;
-}
-
-parse_error::ParseError GAPIGL::SetParamData(ResourceId id,
- unsigned int size,
- const void *data) {
- EffectParamGL *param = effect_params_.Get(id);
- if (!param) return parse_error::kParseInvalidArguments;
- return param->SetData(this, size, data) ?
- parse_error::kParseNoError :
- parse_error::kParseInvalidArguments;
-}
-
-parse_error::ParseError GAPIGL::GetParamDesc(ResourceId id,
- unsigned int size,
- void *data) {
- EffectParamGL *param = effect_params_.Get(id);
- if (!param) return parse_error::kParseInvalidArguments;
- return param->GetDesc(size, data) ?
- parse_error::kParseNoError :
- parse_error::kParseInvalidArguments;
-}
-
-parse_error::ParseError GAPIGL::GetStreamCount(
- ResourceId id,
- unsigned int size,
- void *data) {
- EffectGL *effect = effects_.Get(id);
- if (!effect || size < sizeof(Uint32)) // NOLINT
- return parse_error::kParseInvalidArguments;
- *static_cast<Uint32 *>(data) = effect->GetStreamCount();
- return parse_error::kParseNoError;
-}
-
-parse_error::ParseError GAPIGL::GetStreamDesc(ResourceId id,
- unsigned int index,
- unsigned int size,
- void *data) {
- EffectGL *effect = effects_.Get(id);
- if (!effect) return parse_error::kParseInvalidArguments;
- return effect->GetStreamDesc(index, size, data) ?
- parse_error::kParseNoError :
- parse_error::kParseInvalidArguments;
-}
-
-// If the current effect is valid, call End on it, and tag for revalidation.
-void GAPIGL::DirtyEffect() {
- if (validate_effect_) return;
- DCHECK(current_effect_);
- current_effect_->End(this);
- current_effect_ = NULL;
- validate_effect_ = true;
-}
-
-// Gets the current effect, and calls Begin on it (if successful).
-// Should only be called if the current effect is not valid.
-bool GAPIGL::ValidateEffect() {
- DCHECK(validate_effect_);
- DCHECK(!current_effect_);
- current_effect_ = effects_.Get(current_effect_id_);
- if (!current_effect_) return false;
- validate_effect_ = false;
- return current_effect_->Begin(this);
-}
-
-} // namespace o3d
-} // namespace command_buffer