diff options
author | rlp@google.com <rlp@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-02 23:28:00 +0000 |
---|---|---|
committer | rlp@google.com <rlp@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-02 23:28:00 +0000 |
commit | ac300913ded24c0e6887c72fa48435dc671bd16c (patch) | |
tree | 89a09fe8171122c66f74b1d6fbf2ec6df35ff37d | |
parent | dcdae9eeabbf866f98d7fab10096bb19054458cc (diff) | |
download | chromium_src-ac300913ded24c0e6887c72fa48435dc671bd16c.zip chromium_src-ac300913ded24c0e6887c72fa48435dc671bd16c.tar.gz chromium_src-ac300913ded24c0e6887c72fa48435dc671bd16c.tar.bz2 |
Adding GetStreamInfo functionality (and passing corresponding unit test).
Review URL: http://codereview.chromium.org/147237
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19859 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | o3d/command_buffer/client/cross/effect_helper.cc | 63 | ||||
-rw-r--r-- | o3d/command_buffer/client/cross/effect_helper.h | 21 | ||||
-rw-r--r-- | o3d/command_buffer/common/cross/cmd_buffer_format.h | 2 | ||||
-rw-r--r-- | o3d/command_buffer/common/cross/gapi_interface.h | 28 | ||||
-rw-r--r-- | o3d/command_buffer/common/cross/resource.h | 7 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gapi_decoder.cc | 25 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/resource.h | 7 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/d3d9_utils.h | 53 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/effect_d3d9.cc | 98 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/effect_d3d9.h | 13 | ||||
-rw-r--r-- | o3d/command_buffer/service/win/d3d9/gapi_d3d9.h | 11 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/effect_cb.cc | 59 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/effect_cb.h | 2 |
13 files changed, 384 insertions, 5 deletions
diff --git a/o3d/command_buffer/client/cross/effect_helper.cc b/o3d/command_buffer/client/cross/effect_helper.cc index 0cab6ee..1552e29 100644 --- a/o3d/command_buffer/client/cross/effect_helper.cc +++ b/o3d/command_buffer/client/cross/effect_helper.cc @@ -207,5 +207,68 @@ void EffectHelper::DestroyEffectParameters( } } +bool EffectHelper::GetEffectStreams(ResourceID effect_id, + std::vector<EffectStreamDesc> *descs) { + using effect_stream::Desc; + DCHECK_NE(effect_id, kInvalidResource); + + // Get the param count. + Uint32 *retval = shm_allocator_->AllocTyped<Uint32>(1); + CommandBufferEntry args[5]; + args[0].value_uint32 = effect_id; + args[1].value_uint32 = sizeof(*retval); + args[2].value_uint32 = shm_id_; + args[3].value_uint32 = shm_allocator_->GetOffset(retval); + helper_->AddCommand(GET_STREAM_COUNT, 4, args); + // Finish has to be called to get the result. + helper_->Finish(); + + // We could have failed if the effect_id is invalid. + if (helper_->interface()->GetParseError() != + BufferSyncInterface::PARSE_NO_ERROR) { + shm_allocator_->Free(retval); + return false; + } + unsigned int stream_count = *retval; + shm_allocator_->Free(retval); + unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize(); + if (max_buffer_size < sizeof(Desc)) { // NOLINT + // Not enough memory to get at least 1 stream desc. + return false; + } + descs->resize(stream_count); + + // Read stream descriptions in batches. We use as much shared memory as + // possible so that we only call Finish as little as possible. + unsigned int max_stream_per_batch = + std::min(stream_count, max_buffer_size / sizeof(Desc)); // NOLINT + Desc *raw_descs = shm_allocator_->AllocTyped<Desc>(max_stream_per_batch); + DCHECK(raw_descs); + for (unsigned int i = 0; i < stream_count; i += max_stream_per_batch) { + unsigned int count = std::min(stream_count - i, max_stream_per_batch); + for (unsigned int j = 0 ; j < count; ++j) { + EffectStreamDesc *desc = &((*descs)[i + j]); + Desc *raw_desc = raw_descs + j; + args[0].value_uint32 = effect_id; + args[1].value_uint32 = i+j; + args[2].value_uint32 = sizeof(*raw_desc); + args[3].value_uint32 = shm_id_; + args[4].value_uint32 = shm_allocator_->GetOffset(raw_desc); + helper_->AddCommand(GET_STREAM_DESC, 5, args); + } + // Finish to get the results. + helper_->Finish(); + DCHECK_EQ(helper_->interface()->GetParseError(), + BufferSyncInterface::PARSE_NO_ERROR); + for (unsigned int j = 0 ; j < count; ++j) { + EffectStreamDesc *desc = &((*descs)[i + j]); + Desc *raw_desc = raw_descs + j; + desc->semantic = static_cast<vertex_struct::Semantic>(raw_desc->semantic); + desc->semantic_index = raw_desc->semantic_index; + } + } + shm_allocator_->Free(raw_descs); + return true; +} } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/client/cross/effect_helper.h b/o3d/command_buffer/client/cross/effect_helper.h index 19523ee..4c62487 100644 --- a/o3d/command_buffer/client/cross/effect_helper.h +++ b/o3d/command_buffer/client/cross/effect_helper.h @@ -59,6 +59,10 @@ class EffectHelper { // structure (counting strings) for a // param. }; + struct EffectStreamDesc { + vertex_struct::Semantic semantic; // The semantic enum type. + unsigned int semantic_index; + }; EffectHelper(CommandBufferHelper *helper, FencedAllocatorWrapper *shm_allocator, @@ -119,6 +123,23 @@ class EffectHelper { // descs: the vector of descriptions containing the ResourceIDs of the // parameters to destroy. void DestroyEffectParameters(const std::vector<EffectParamDesc> &descs); + + // Gets all the input stream semantics and semantic indices in an + // array. These will be retrieved as many as possible at a time. At least + // sizeof(effect_param::Desc) must be available for this function to succeed. + // This function will call Finish(), hence will block. + // + // Parameters: + // effect_id: the ResourceID of the effect. + // descs: A pointer to a vector containing the returned descriptions. + // The pointed vector will be cleared. + // Returns: + // true if successful. Reasons for failure are: + // - invalid effect_id, + // - not enough memory in the shm_allocator_. + bool GetEffectStreams(ResourceID effect_id, + std::vector<EffectStreamDesc> *descs); + private: CommandBufferHelper *helper_; FencedAllocatorWrapper *shm_allocator_; diff --git a/o3d/command_buffer/common/cross/cmd_buffer_format.h b/o3d/command_buffer/common/cross/cmd_buffer_format.h index b0b9386..1872a34 100644 --- a/o3d/command_buffer/common/cross/cmd_buffer_format.h +++ b/o3d/command_buffer/common/cross/cmd_buffer_format.h @@ -293,6 +293,8 @@ enum CommandId { SET_PARAM_DATA, // SetParamData, 4 args SET_PARAM_DATA_IMMEDIATE, // SetParamData, 2 args + data GET_PARAM_DESC, // GetParamDesc, 4 args + GET_STREAM_COUNT, // GetStreamCount, 4 args. + GET_STREAM_DESC, // GetStreamDesc, 5 args DESTROY_TEXTURE, // DestroyTexture, 1 arg CREATE_TEXTURE_2D, // CreateTexture2D, 3 args CREATE_TEXTURE_3D, // CreateTexture3D, 4 args diff --git a/o3d/command_buffer/common/cross/gapi_interface.h b/o3d/command_buffer/common/cross/gapi_interface.h index 9531973..67700b7 100644 --- a/o3d/command_buffer/common/cross/gapi_interface.h +++ b/o3d/command_buffer/common/cross/gapi_interface.h @@ -481,6 +481,34 @@ class GAPIInterface { unsigned int size, void *data) = 0; + // Gets the number of input streams for an effect, returning it in a memory + // buffer as a Uint32. + // Parameters: + // id: the resource ID of the effect. + // size: the size of the data buffer. Must be at least 4 (the size of the + // Uint32). + // data: the buffer receiving the data. + // Returns: + // BufferSyncInterface::PARSE_INVALID_ARGUMENTS if invalid arguments are + // passed, BufferSyncInterface::PARSE_NO_ERROR otherwise. + virtual ParseError GetStreamCount(ResourceID id, + unsigned int size, + void *data) = 0; + + // Gets the stream semantics, storing them in the data buffer. The stream + // is described by an effect_stream::Desc structure which contains a + // semantic type and a semantic index. + // Parameters: + // id: the resource ID of the effect. + // index: which stream semantic to get + // size: the size of the data buffer. Must be at least 8 (the size of two + // Uint32). + // data: the buffer receiving the data. + virtual ParseError GetStreamDesc(ResourceID id, + unsigned int index, + unsigned int size, + void *data) = 0; + // Creates a 2D texture resource. // Parameters: // id: the resource ID of the texture. diff --git a/o3d/command_buffer/common/cross/resource.h b/o3d/command_buffer/common/cross/resource.h index 8e86723..861d24f 100644 --- a/o3d/command_buffer/common/cross/resource.h +++ b/o3d/command_buffer/common/cross/resource.h @@ -134,6 +134,13 @@ struct Desc { }; } // namespace effect_param +namespace effect_stream { +struct Desc { + Uint32 semantic; // the semantic type + Uint32 semantic_index; +}; +} // namespace effect_stream + namespace texture { // Texture flags. enum Flags { diff --git a/o3d/command_buffer/service/cross/gapi_decoder.cc b/o3d/command_buffer/service/cross/gapi_decoder.cc index efd3bc5..dfd0cff 100644 --- a/o3d/command_buffer/service/cross/gapi_decoder.cc +++ b/o3d/command_buffer/service/cross/gapi_decoder.cc @@ -367,6 +367,31 @@ BufferSyncInterface::ParseError GAPIDecoder::DoCommand( } else { return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } + case GET_STREAM_COUNT: + if (arg_count == 4) { + ResourceID id = args[0].value_uint32; + unsigned int size = args[1].value_uint32; + void *data = GetAddressAndCheckSize(args[2].value_uint32, + args[3].value_uint32, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamCount(id, size, data); + } else { + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + } + case GET_STREAM_DESC: + if (arg_count == 5) { + ResourceID id = args[0].value_uint32; + unsigned int index = args[1].value_uint32; + unsigned int size = args[2].value_uint32; + void *data = GetAddressAndCheckSize(args[3].value_uint32, + args[4].value_uint32, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamDesc(id, index, size, data); + } else { + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + } case DESTROY_TEXTURE: if (arg_count == 1) { return gapi_->DestroyTexture(args[0].value_uint32); diff --git a/o3d/command_buffer/service/cross/resource.h b/o3d/command_buffer/service/cross/resource.h index 5c6e6ed..9df3ca4 100644 --- a/o3d/command_buffer/service/cross/resource.h +++ b/o3d/command_buffer/service/cross/resource.h @@ -153,6 +153,13 @@ class EffectParam: public Resource { DISALLOW_COPY_AND_ASSIGN(EffectParam); }; +class EffectStream: public Resource { + public: + explicit EffectStream() {} + private: + DISALLOW_COPY_AND_ASSIGN(EffectStream); +}; + // Texture class, representing a texture resource. class Texture: public Resource { public: diff --git a/o3d/command_buffer/service/win/d3d9/d3d9_utils.h b/o3d/command_buffer/service/win/d3d9/d3d9_utils.h index 647d984..17cd621 100644 --- a/o3d/command_buffer/service/win/d3d9/d3d9_utils.h +++ b/o3d/command_buffer/service/win/d3d9/d3d9_utils.h @@ -96,6 +96,59 @@ inline D3DCOLOR RGBAToD3DCOLOR(const RGBA &color) { FloatToClampedByte(color.alpha)); } +inline bool VerifyHResult(HRESULT hr, const char* file, int line, + const char* call) { + if (FAILED(hr)) { + DLOG(ERROR) << "DX Error in file " << file + << " line " << line << L": " + << DXGetErrorStringA(hr) << L": " << call; + return false; + } + return true; +} + +static bool D3DSemanticToCBSemantic( + D3DDECLUSAGE semantic, + unsigned int semantic_index, + vertex_struct::Semantic *out_semantic, + unsigned int *out_semantic_index) { + // TODO: what meaning do we really want to put to our semantics ? How + // do they match the semantics that are set in the effect ? What combination + // of (semantic, index) are supposed to work ? + switch (semantic) { + case D3DDECLUSAGE_POSITION: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::POSITION; + *out_semantic_index = 0; + return true; + case D3DDECLUSAGE_NORMAL: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::NORMAL; + *out_semantic_index = 0; + return true; + case D3DDECLUSAGE_TANGENT: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::TEX_COORD; + *out_semantic_index = 6; + return true; + case D3DDECLUSAGE_BINORMAL: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::TEX_COORD; + *out_semantic_index = 7; + return true; + case D3DDECLUSAGE_COLOR: + if (semantic_index > 1) return false; + *out_semantic = vertex_struct::COLOR; + *out_semantic_index = semantic_index; + return true; + case D3DDECLUSAGE_TEXCOORD: + *out_semantic = vertex_struct::TEX_COORD; + *out_semantic_index = semantic_index; + return true; + default: + return false; + } +} } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc index 7cfee14..c55c345 100644 --- a/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc +++ b/o3d/command_buffer/service/win/d3d9/effect_d3d9.cc @@ -69,13 +69,16 @@ static void LogFXError(LPD3DXBUFFER error_buffer) { } EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect, - ID3DXConstantTable *fs_constant_table) + ID3DXConstantTable *fs_constant_table, + IDirect3DVertexShader9 *d3d_vertex_shader) : d3d_effect_(d3d_effect), fs_constant_table_(fs_constant_table), + d3d_vertex_shader_(d3d_vertex_shader), sync_parameters_(false) { for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { samplers_[i] = kInvalidResource; } + SetStreams(); } // Releases the D3D effect. EffectD3D9::~EffectD3D9() { @@ -86,6 +89,8 @@ EffectD3D9::~EffectD3D9() { d3d_effect_->Release(); DCHECK(fs_constant_table_); fs_constant_table_->Release(); + DCHECK(d3d_vertex_shader_); + d3d_vertex_shader_->Release(); } // Compiles the effect, and checks that the effect conforms to what we expect @@ -152,7 +157,17 @@ EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, d3d_effect->Release(); return NULL; } - return new EffectD3D9(d3d_effect, table); + IDirect3DVertexShader9 *d3d_vertex_shader = NULL; + HR(device->CreateVertexShader(pass_desc.pVertexShaderFunction, + &d3d_vertex_shader)); + if (!d3d_vertex_shader) { + d3d_effect->Release(); + table->Release(); + DLOG(ERROR) << "Failed to create vertex shader"; + return NULL; + } + + return new EffectD3D9(d3d_effect, table, d3d_vertex_shader); } // Begins rendering with the effect, setting all the appropriate states. @@ -177,6 +192,11 @@ unsigned int EffectD3D9::GetParamCount() { return effect_desc.Parameters; } +// Gets the number of input streams from the shader. +unsigned int EffectD3D9::GetStreamCount() { + return streams_.size(); +} + // Retrieves the matching DataType from a D3D parameter description. static effect_param::DataType GetDataTypeFromD3D( const D3DXPARAMETER_DESC &desc) { @@ -282,6 +302,38 @@ bool EffectD3D9::SetSamplers(GAPID3D9 *gapi) { return result; } +bool EffectD3D9::SetStreams() { + if (!d3d_vertex_shader_) { + return false; + } + UINT size; + d3d_vertex_shader_->GetFunction(NULL, &size); + scoped_array<DWORD> function(new DWORD[size]); + d3d_vertex_shader_->GetFunction(function.get(), &size); + + UINT num_semantics; + HR(D3DXGetShaderInputSemantics(function.get(), + NULL, + &num_semantics)); + scoped_array<D3DXSEMANTIC> semantics(new D3DXSEMANTIC[num_semantics]); + HR(D3DXGetShaderInputSemantics(function.get(), + semantics.get(), + &num_semantics)); + + streams_.resize(num_semantics); + for (UINT i = 0; i < num_semantics; ++i) { + vertex_struct::Semantic semantic; + unsigned int semantic_index; + if (D3DSemanticToCBSemantic(static_cast<D3DDECLUSAGE>(semantics[i].Usage), + static_cast<int>(semantics[i].UsageIndex), + &semantic, &semantic_index)) { + streams_[i].semantic = semantic; + streams_[i].semantic_index = semantic_index; + } + } + return true; +} + void EffectD3D9::LinkParam(EffectParamD3D9 *param) { params_.push_back(param); } @@ -290,6 +342,23 @@ void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) { std::remove(params_.begin(), params_.end(), param); } +// Fills the Desc structure, appending name and semantic if any, and if enough +// room is available in the buffer. +bool EffectD3D9::GetStreamDesc(unsigned int index, + unsigned int size, + void *data) { + using effect_stream::Desc; + if (size < sizeof(Desc)) // NOLINT + return false; + + Desc stream = streams_[index]; + Desc *desc = static_cast<Desc *>(data); + memset(desc, 0, sizeof(*desc)); + desc->semantic = stream.semantic; + desc->semantic_index = stream.semantic_index; + return true; +} + EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type, EffectD3D9 *effect, D3DXHANDLE handle) @@ -559,6 +628,31 @@ BufferSyncInterface::ParseError GAPID3D9::GetParamDesc( BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } +// Gets the stream count from the effect and store it in the memory buffer. +BufferSyncInterface::ParseError GAPID3D9::GetStreamCount( + ResourceID id, + unsigned int size, + void *data) { + EffectD3D9 *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 GAPID3D9::GetStreamDesc( + ResourceID id, + unsigned int index, + unsigned int size, + void *data) { + EffectD3D9 *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 GAPID3D9::DirtyEffect() { if (validate_effect_) return; diff --git a/o3d/command_buffer/service/win/d3d9/effect_d3d9.h b/o3d/command_buffer/service/win/d3d9/effect_d3d9.h index 318598c..1180fb8 100644 --- a/o3d/command_buffer/service/win/d3d9/effect_d3d9.h +++ b/o3d/command_buffer/service/win/d3d9/effect_d3d9.h @@ -80,7 +80,8 @@ class EffectParamD3D9: public EffectParam { class EffectD3D9 : public Effect { public: EffectD3D9(ID3DXEffect *d3d_effect, - ID3DXConstantTable *fs_constant_table); + ID3DXConstantTable *fs_constant_table, + IDirect3DVertexShader9 *d3d_vertex_shader); virtual ~EffectD3D9(); // Compiles and creates an effect from source code. static EffectD3D9 *Create(GAPID3D9 *gapi, @@ -101,8 +102,13 @@ class EffectD3D9 : public Effect { EffectParamD3D9 *CreateParam(unsigned int index); // Creates an effect parameter of the specified name. EffectParamD3D9 *CreateParamByName(const char *name); + // Gets the number of stream inputs for the effect. + unsigned int GetStreamCount(); + // Gets the stream data with the specified index. + bool GetStreamDesc(unsigned int index, unsigned int size, void *data); private: typedef std::vector<EffectParamD3D9 *> ParamList; + typedef std::vector<effect_stream::Desc> StreamList; // Links a param into this effect. void LinkParam(EffectParamD3D9 *param); @@ -110,14 +116,19 @@ class EffectD3D9 : public Effect { void UnlinkParam(EffectParamD3D9 *param); // Sets sampler states. bool SetSamplers(GAPID3D9 *gapi); + // Sets streams vector. + bool SetStreams(); ID3DXEffect *d3d_effect_; + IDirect3DVertexShader9 *d3d_vertex_shader_; ID3DXConstantTable *fs_constant_table_; ParamList params_; + StreamList streams_; bool sync_parameters_; ResourceID samplers_[kMaxSamplerUnits]; friend class EffectParamD3D9; + friend class EffectStreamD3D9; DISALLOW_COPY_AND_ASSIGN(EffectD3D9); }; diff --git a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h index e94f35c..c757cc6 100644 --- a/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h +++ b/o3d/command_buffer/service/win/d3d9/gapi_d3d9.h @@ -195,6 +195,17 @@ class GAPID3D9 : public GAPIInterface { unsigned int size, void *data); + // Implements the GetStreamCount function for D3D9. + virtual ParseError GetStreamCount(ResourceID id, + unsigned int size, + void *data); + + // Implements the GetStreamDesc function for D3D9. + virtual ParseError GetStreamDesc(ResourceID id, + unsigned int index, + unsigned int size, + void *data); + // Implements the CreateTexture2D function for D3D9. virtual ParseError CreateTexture2D(ResourceID id, unsigned int width, diff --git a/o3d/core/cross/command_buffer/effect_cb.cc b/o3d/core/cross/command_buffer/effect_cb.cc index afa9e0f..27afbd7 100644 --- a/o3d/core/cross/command_buffer/effect_cb.cc +++ b/o3d/core/cross/command_buffer/effect_cb.cc @@ -49,6 +49,7 @@ using command_buffer::CommandBufferEntry; using command_buffer::CommandBufferHelper; using command_buffer::ResourceID; namespace effect_param = command_buffer::effect_param; +namespace vertex_struct = command_buffer::vertex_struct; EffectCB::EffectCB(ServiceLocator *service_locator, RendererCB *renderer) : Effect(service_locator), @@ -125,6 +126,11 @@ bool EffectCB::LoadFromFXString(const String& source) { return false; } } + if (!effect_helper.GetEffectStreams(resource_id, &stream_descs_)) { + O3D_ERROR(service_locator()) << "Failed to get streams."; + Destroy(); + return false; + } set_source(source); return true; } @@ -200,8 +206,59 @@ void EffectCB::GetParameterInfo(EffectParameterInfoArray *array) { } } + +static bool CBSemanticToO3DSemantic( + vertex_struct::Semantic semantic, + unsigned int semantic_index, + Stream::Semantic *out_semantic, + unsigned int *out_semantic_index) { + switch (semantic) { + case vertex_struct::POSITION: + if (semantic_index != 0) return false; + *out_semantic = Stream::POSITION; + *out_semantic_index = 0; + return true; + case vertex_struct::NORMAL: + if (semantic_index != 0) return false; + *out_semantic = Stream::NORMAL; + *out_semantic_index = 0; + return true; + case vertex_struct::COLOR: + if (semantic_index > 1) return false; + *out_semantic = Stream::COLOR; + *out_semantic_index = semantic_index; + return true; + case vertex_struct::TEX_COORD: + if (semantic_index == 6) { + *out_semantic = Stream::TANGENT; + *out_semantic_index = 0; + return true; + } else if (semantic_index == 7) { + *out_semantic = Stream::BINORMAL; + *out_semantic_index = 0; + return true; + } else { + *out_semantic = Stream::TEXCOORD; + *out_semantic_index = semantic_index; + return true; + } + default: + return false; + } +} void EffectCB::GetStreamInfo(EffectStreamInfoArray *array) { - // TODO(rlp) + DCHECK(array); + array->clear(); + for (unsigned int i = 0; i < stream_descs_.size(); ++i) { + Stream::Semantic semantic; + unsigned int semantic_index; + if (CBSemanticToO3DSemantic(stream_descs_[i].semantic, + stream_descs_[i].semantic_index, + &semantic, + &semantic_index)) { + array->push_back(EffectStreamInfo(semantic, semantic_index)); + } + } } } // namespace o3d diff --git a/o3d/core/cross/command_buffer/effect_cb.h b/o3d/core/cross/command_buffer/effect_cb.h index a50638e..3d310bc 100644 --- a/o3d/core/cross/command_buffer/effect_cb.h +++ b/o3d/core/cross/command_buffer/effect_cb.h @@ -75,9 +75,9 @@ class EffectCB : public Effect { // The command buffer resource ID for the effect. command_buffer::ResourceID resource_id_; std::vector<EffectHelper::EffectParamDesc> param_descs_; + std::vector<EffectHelper::EffectStreamDesc> stream_descs_; // A generation counter to dirty ParamCacheCBs. unsigned int generation_; - // The renderer that created this effect. RendererCB *renderer_; DISALLOW_IMPLICIT_CONSTRUCTORS(EffectCB); |