OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 reinterpret_cast<wchar_t*>(&hLocal), | 62 reinterpret_cast<wchar_t*>(&hLocal), |
63 0, | 63 0, |
64 NULL); | 64 NULL); |
65 wchar_t* msg = reinterpret_cast<wchar_t*>(LocalLock(hLocal)); | 65 wchar_t* msg = reinterpret_cast<wchar_t*>(LocalLock(hLocal)); |
66 LOG(ERROR) << "Failed to compile effect: " << msg; | 66 LOG(ERROR) << "Failed to compile effect: " << msg; |
67 LocalFree(hLocal); | 67 LocalFree(hLocal); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect, | 71 EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect, |
72 ID3DXConstantTable *fs_constant_table) | 72 ID3DXConstantTable *fs_constant_table, |
73 IDirect3DVertexShader9 *d3d_vertex_shader) | |
73 : d3d_effect_(d3d_effect), | 74 : d3d_effect_(d3d_effect), |
74 fs_constant_table_(fs_constant_table), | 75 fs_constant_table_(fs_constant_table), |
76 d3d_vertex_shader_(d3d_vertex_shader), | |
75 sync_parameters_(false) { | 77 sync_parameters_(false) { |
76 for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { | 78 for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { |
77 samplers_[i] = kInvalidResource; | 79 samplers_[i] = kInvalidResource; |
78 } | 80 } |
81 SetStreams(); | |
79 } | 82 } |
80 // Releases the D3D effect. | 83 // Releases the D3D effect. |
81 EffectD3D9::~EffectD3D9() { | 84 EffectD3D9::~EffectD3D9() { |
82 for (ParamList::iterator it = params_.begin(); it != params_.end(); ++it) { | 85 for (ParamList::iterator it = params_.begin(); it != params_.end(); ++it) { |
83 (*it)->ResetEffect(); | 86 (*it)->ResetEffect(); |
84 } | 87 } |
85 DCHECK(d3d_effect_); | 88 DCHECK(d3d_effect_); |
86 d3d_effect_->Release(); | 89 d3d_effect_->Release(); |
87 DCHECK(fs_constant_table_); | 90 DCHECK(fs_constant_table_); |
88 fs_constant_table_->Release(); | 91 fs_constant_table_->Release(); |
92 DCHECK(d3d_vertex_shader_); | |
93 d3d_vertex_shader_->Release(); | |
89 } | 94 } |
90 | 95 |
91 // Compiles the effect, and checks that the effect conforms to what we expect | 96 // Compiles the effect, and checks that the effect conforms to what we expect |
92 // (no extra technique or pass in the effect code, since one is implicitly added | 97 // (no extra technique or pass in the effect code, since one is implicitly added |
93 // using the program entry points) and that it validates. If successful, wrap | 98 // using the program entry points) and that it validates. If successful, wrap |
94 // the D3D effect into a new EffectD3D9. | 99 // the D3D effect into a new EffectD3D9. |
95 EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, | 100 EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, |
96 const String& effect_code, | 101 const String& effect_code, |
97 const String& vertex_program_entry, | 102 const String& vertex_program_entry, |
98 const String& fragment_program_entry) { | 103 const String& fragment_program_entry) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 D3DXPASS_DESC pass_desc; | 150 D3DXPASS_DESC pass_desc; |
146 HR(d3d_effect->GetPassDesc(pass, &pass_desc)); | 151 HR(d3d_effect->GetPassDesc(pass, &pass_desc)); |
147 ID3DXConstantTable *table = NULL; | 152 ID3DXConstantTable *table = NULL; |
148 HR(D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, | 153 HR(D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, |
149 &table)); | 154 &table)); |
150 if (!table) { | 155 if (!table) { |
151 LOG(ERROR) << "Could not get the constant table."; | 156 LOG(ERROR) << "Could not get the constant table."; |
152 d3d_effect->Release(); | 157 d3d_effect->Release(); |
153 return NULL; | 158 return NULL; |
154 } | 159 } |
155 return new EffectD3D9(d3d_effect, table); | 160 IDirect3DVertexShader9 *d3d_vertex_shader = NULL; |
161 HR(device->CreateVertexShader(pass_desc.pVertexShaderFunction, | |
162 &d3d_vertex_shader)); | |
163 if (!d3d_vertex_shader) { | |
164 d3d_effect->Release(); | |
165 table->Release(); | |
166 DLOG(ERROR) << "Failed to create vertex shader"; | |
167 return NULL; | |
168 } | |
169 | |
170 return new EffectD3D9(d3d_effect, table, d3d_vertex_shader); | |
156 } | 171 } |
157 | 172 |
158 // Begins rendering with the effect, setting all the appropriate states. | 173 // Begins rendering with the effect, setting all the appropriate states. |
159 bool EffectD3D9::Begin(GAPID3D9 *gapi) { | 174 bool EffectD3D9::Begin(GAPID3D9 *gapi) { |
160 UINT numpasses; | 175 UINT numpasses; |
161 HR(d3d_effect_->Begin(&numpasses, 0)); | 176 HR(d3d_effect_->Begin(&numpasses, 0)); |
162 HR(d3d_effect_->BeginPass(0)); | 177 HR(d3d_effect_->BeginPass(0)); |
163 sync_parameters_ = false; | 178 sync_parameters_ = false; |
164 return SetSamplers(gapi); | 179 return SetSamplers(gapi); |
165 } | 180 } |
166 | 181 |
167 // Terminates rendering with the effect, resetting all the appropriate states. | 182 // Terminates rendering with the effect, resetting all the appropriate states. |
168 void EffectD3D9::End(GAPID3D9 *gapi) { | 183 void EffectD3D9::End(GAPID3D9 *gapi) { |
169 HR(d3d_effect_->EndPass()); | 184 HR(d3d_effect_->EndPass()); |
170 HR(d3d_effect_->End()); | 185 HR(d3d_effect_->End()); |
171 } | 186 } |
172 | 187 |
173 // Gets the parameter count from the D3D effect description. | 188 // Gets the parameter count from the D3D effect description. |
174 unsigned int EffectD3D9::GetParamCount() { | 189 unsigned int EffectD3D9::GetParamCount() { |
175 D3DXEFFECT_DESC effect_desc; | 190 D3DXEFFECT_DESC effect_desc; |
176 HR(d3d_effect_->GetDesc(&effect_desc)); | 191 HR(d3d_effect_->GetDesc(&effect_desc)); |
177 return effect_desc.Parameters; | 192 return effect_desc.Parameters; |
178 } | 193 } |
179 | 194 |
195 // Gets the number of input streams from the shader. | |
196 unsigned int EffectD3D9::GetStreamCount() { | |
197 return streams_.size(); | |
198 } | |
199 | |
180 // Retrieves the matching DataType from a D3D parameter description. | 200 // Retrieves the matching DataType from a D3D parameter description. |
181 static effect_param::DataType GetDataTypeFromD3D( | 201 static effect_param::DataType GetDataTypeFromD3D( |
182 const D3DXPARAMETER_DESC &desc) { | 202 const D3DXPARAMETER_DESC &desc) { |
183 switch (desc.Type) { | 203 switch (desc.Type) { |
184 case D3DXPT_FLOAT: | 204 case D3DXPT_FLOAT: |
185 switch (desc.Class) { | 205 switch (desc.Class) { |
186 case D3DXPC_SCALAR: | 206 case D3DXPC_SCALAR: |
187 return effect_param::FLOAT1; | 207 return effect_param::FLOAT1; |
188 case D3DXPC_VECTOR: | 208 case D3DXPC_VECTOR: |
189 switch (desc.Columns) { | 209 switch (desc.Columns) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 SamplerD3D9 *sampler = gapi->GetSampler(samplers_[i]); | 295 SamplerD3D9 *sampler = gapi->GetSampler(samplers_[i]); |
276 if (sampler) { | 296 if (sampler) { |
277 result &= sampler->ApplyStates(gapi, i); | 297 result &= sampler->ApplyStates(gapi, i); |
278 } else { | 298 } else { |
279 HR(d3d_device->SetTexture(i, NULL)); | 299 HR(d3d_device->SetTexture(i, NULL)); |
280 } | 300 } |
281 } | 301 } |
282 return result; | 302 return result; |
283 } | 303 } |
284 | 304 |
305 bool EffectD3D9::SetStreams() { | |
306 if (!d3d_vertex_shader_) { | |
307 return false; | |
308 } | |
309 UINT size; | |
310 d3d_vertex_shader_->GetFunction(NULL, &size); | |
311 scoped_array<DWORD> function(new DWORD[size]); | |
312 d3d_vertex_shader_->GetFunction(function.get(), &size); | |
313 | |
314 UINT num_semantics; | |
315 HR(D3DXGetShaderInputSemantics(function.get(), | |
316 NULL, | |
317 &num_semantics)); | |
318 scoped_array<D3DXSEMANTIC> semantics(new D3DXSEMANTIC[num_semantics]); | |
319 HR(D3DXGetShaderInputSemantics(function.get(), | |
320 semantics.get(), | |
321 &num_semantics)); | |
322 | |
323 streams_.resize(num_semantics); | |
324 for (UINT i = 0; i < num_semantics; ++i) { | |
325 vertex_struct::Semantic semantic; | |
326 unsigned int semantic_index; | |
327 if (D3DSemanticToCBSemantic(static_cast<D3DDECLUSAGE>(semantics[i].Usage), | |
328 static_cast<int>(semantics[i].UsageIndex), | |
329 &semantic, &semantic_index)) { | |
330 streams_[i].semantic = semantic; | |
331 streams_[i].semantic_index = semantic_index; | |
332 } | |
333 } | |
334 return true; | |
335 } | |
336 | |
285 void EffectD3D9::LinkParam(EffectParamD3D9 *param) { | 337 void EffectD3D9::LinkParam(EffectParamD3D9 *param) { |
286 params_.push_back(param); | 338 params_.push_back(param); |
287 } | 339 } |
288 | 340 |
289 void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) { | 341 void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) { |
290 std::remove(params_.begin(), params_.end(), param); | 342 std::remove(params_.begin(), params_.end(), param); |
291 } | 343 } |
292 | 344 |
345 // Fills the Desc structure, appending name and semantic if any, and if enough | |
346 // room is available in the buffer. | |
347 bool EffectD3D9::GetStreamDesc(unsigned int index, | |
348 unsigned int size, | |
349 void *data) { | |
350 using effect_stream::Desc; | |
351 if (size < sizeof(Desc)) // NOLINT | |
352 return false; | |
353 | |
354 Desc stream = streams_[index]; | |
355 Desc *desc = static_cast<Desc *>(data); | |
356 memset(desc, 0, sizeof(*desc)); | |
357 desc->semantic = stream.semantic; | |
358 desc->semantic_index = stream.semantic_index; | |
Antoine Labour
2009/07/06 23:48:12
how about simply *desc = streams_[index]; instead
| |
359 return true; | |
360 } | |
361 | |
293 EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type, | 362 EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type, |
294 EffectD3D9 *effect, | 363 EffectD3D9 *effect, |
295 D3DXHANDLE handle) | 364 D3DXHANDLE handle) |
296 : EffectParam(data_type), | 365 : EffectParam(data_type), |
297 effect_(effect), | 366 effect_(effect), |
298 handle_(handle), | 367 handle_(handle), |
299 sampler_units_(NULL), | 368 sampler_units_(NULL), |
300 sampler_unit_count_(0) { | 369 sampler_unit_count_(0) { |
301 DCHECK(effect_); | 370 DCHECK(effect_); |
302 effect_->LinkParam(this); | 371 effect_->LinkParam(this); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 ResourceID id, | 621 ResourceID id, |
553 unsigned int size, | 622 unsigned int size, |
554 void *data) { | 623 void *data) { |
555 EffectParamD3D9 *param = effect_params_.Get(id); | 624 EffectParamD3D9 *param = effect_params_.Get(id); |
556 if (!param) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; | 625 if (!param) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; |
557 return param->GetDesc(size, data) ? | 626 return param->GetDesc(size, data) ? |
558 BufferSyncInterface::PARSE_NO_ERROR : | 627 BufferSyncInterface::PARSE_NO_ERROR : |
559 BufferSyncInterface::PARSE_INVALID_ARGUMENTS; | 628 BufferSyncInterface::PARSE_INVALID_ARGUMENTS; |
560 } | 629 } |
561 | 630 |
631 // Gets the stream count from the effect and store it in the memory buffer. | |
632 BufferSyncInterface::ParseError GAPID3D9::GetStreamCount( | |
633 ResourceID id, | |
634 unsigned int size, | |
635 void *data) { | |
636 EffectD3D9 *effect = effects_.Get(id); | |
637 if (!effect || size < sizeof(Uint32)) // NOLINT | |
638 return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; | |
639 *static_cast<Uint32 *>(data) = effect->GetStreamCount(); | |
640 return BufferSyncInterface::PARSE_NO_ERROR; | |
641 } | |
642 | |
643 BufferSyncInterface::ParseError GAPID3D9::GetStreamDesc( | |
644 ResourceID id, | |
645 unsigned int index, | |
646 unsigned int size, | |
647 void *data) { | |
648 EffectD3D9 *effect = effects_.Get(id); | |
649 if (!effect) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; | |
650 return effect->GetStreamDesc(index, size, data) ? | |
651 BufferSyncInterface::PARSE_NO_ERROR : | |
652 BufferSyncInterface::PARSE_INVALID_ARGUMENTS; | |
653 } | |
654 | |
655 | |
562 // If the current effect is valid, call End on it, and tag for revalidation. | 656 // If the current effect is valid, call End on it, and tag for revalidation. |
563 void GAPID3D9::DirtyEffect() { | 657 void GAPID3D9::DirtyEffect() { |
564 if (validate_effect_) return; | 658 if (validate_effect_) return; |
565 DCHECK(current_effect_); | 659 DCHECK(current_effect_); |
566 current_effect_->End(this); | 660 current_effect_->End(this); |
567 current_effect_ = NULL; | 661 current_effect_ = NULL; |
568 validate_effect_ = true; | 662 validate_effect_ = true; |
569 } | 663 } |
570 | 664 |
571 // Gets the current effect, and calls Begin on it (if successful). | 665 // Gets the current effect, and calls Begin on it (if successful). |
572 // Should only be called if the current effect is not valid. | 666 // Should only be called if the current effect is not valid. |
573 bool GAPID3D9::ValidateEffect() { | 667 bool GAPID3D9::ValidateEffect() { |
574 DCHECK(validate_effect_); | 668 DCHECK(validate_effect_); |
575 DCHECK(!current_effect_); | 669 DCHECK(!current_effect_); |
576 current_effect_ = effects_.Get(current_effect_id_); | 670 current_effect_ = effects_.Get(current_effect_id_); |
577 if (!current_effect_) return false; | 671 if (!current_effect_) return false; |
578 validate_effect_ = false; | 672 validate_effect_ = false; |
579 return current_effect_->Begin(this); | 673 return current_effect_->Begin(this); |
580 } | 674 } |
581 | 675 |
582 } // namespace command_buffer | 676 } // namespace command_buffer |
583 } // namespace o3d | 677 } // namespace o3d |
OLD | NEW |