1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ResTextureMapper.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 18139 $
14 *---------------------------------------------------------------------------*/
15
16 #include "../precompiled.h"
17
18 #include <nw/gfx/res/gfx_ResUtil.h>
19 #include <nw/gfx/res/gfx_ResTextureMapper.h>
20 #include <nw/gfx/res/gfx_ResGraphicsFile.h>
21 #include <nw/gfx/gfx_CommandUtil.h>
22
23 namespace nw {
24 namespace gfx {
25 namespace res {
26
27 typedef Result (*SetupFunc)(ResTextureMapper resTextureMapper, os::IAllocator* allocator, ResGraphicsFile graphicsFile);
28 typedef void (*CleanupFunc)(ResTextureMapper resTextureMapper);
29 typedef ResTextureMapper (*CloneDynamicFunc)(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
30 typedef void (*DestroyDynamicFunc)(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
31
32 static Result ResPixelBasedTextureMapper_Setup(ResTextureMapper resTextureMapper, os::IAllocator* allocator, ResGraphicsFile graphicsFile);
33 static Result ResProceduralTextureMapper_Setup(ResTextureMapper resTextureMapper, os::IAllocator* allocator, ResGraphicsFile graphicsFile);
34 static void ResPixelBasedTextureMapper_Cleanup(ResTextureMapper resTextureMapper);
35 static void ResProceduralTextureMapper_Cleanup(ResTextureMapper resTextureMapper);
36 static ResTextureMapper ResPixelBasedTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
37 static ResTextureMapper ResProceduralTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
38 static void ResPixelBasedTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
39 static void ResProceduralTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator);
40
41 static ResTexture ReferResTexture(os::IAllocator* allocator, ResTexture resTexture);
42
43 static Result SetupTexture(
44 os::IAllocator* allocator,
45 ResTexture resTexture,
46 ResGraphicsFile graphicsFile
47 );
48
49 static void SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResImageTexture texture);
50 static void SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResCubeTexture texture);
51 static void SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResShadowTexture texture);
52
53 static SetupFunc s_TextureMapperSetupTable[] =
54 {
55 ResPixelBasedTextureMapper_Setup,
56 ResProceduralTextureMapper_Setup
57 };
58
59 static CleanupFunc s_TextureMapperCleanupTable[] =
60 {
61 ResPixelBasedTextureMapper_Cleanup,
62 ResProceduralTextureMapper_Cleanup
63 };
64
65 static CloneDynamicFunc s_TextureMapperCloneDynamicTable[] =
66 {
67 ResPixelBasedTextureMapper_CloneDynamic,
68 ResProceduralTextureMapper_CloneDynamic
69 };
70
71 static DestroyDynamicFunc s_TextureMapperDestroyDynamicTable[] =
72 {
73 ResPixelBasedTextureMapper_DestroyDynamic,
74 ResProceduralTextureMapper_DestroyDynamic
75 };
76
77 //----------------------------------------
78 ::std::pair<u32, u32*>
GetOwnerCommand() const79 ResTextureSampler::GetOwnerCommand() const
80 {
81 ResPixelBasedTextureMapper textureMapper =
82 ResStaticCast<ResPixelBasedTextureMapper>(ResTextureMapper(this->GetOwnerData()));
83
84 return ::std::make_pair(textureMapper.GetCommandSizeToSend(), textureMapper.GetCommandCache());
85 }
86
87 /*!--------------------------------------------------------------------------*
88 @brief ピクセルベーステクスチャマッパーをセットアップします。
89
90 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
91 @param[in] allocator アロケータです。
92 @param[in] graphicsFile グラフィックスファイルです。
93 *---------------------------------------------------------------------------*/
94 static Result
ResPixelBasedTextureMapper_Setup(ResTextureMapper resTextureMapper,os::IAllocator * allocator,ResGraphicsFile graphicsFile)95 ResPixelBasedTextureMapper_Setup(ResTextureMapper resTextureMapper, os::IAllocator* allocator, ResGraphicsFile graphicsFile)
96 {
97 ResPixelBasedTextureMapper resPixelBasedTextureMapper =
98 ResStaticCast<ResPixelBasedTextureMapper>(resTextureMapper);
99 ResTexture resTexture = resTextureMapper.GetTexture();
100
101 Result result = SetupTexture(allocator, resTexture, graphicsFile);
102
103 if (result.IsFailure())
104 {
105 return result;
106 }
107
108 ResTexture resImageTexture = resTexture.Dereference();
109
110 switch ( resImageTexture.ref().typeInfo )
111 {
112 case ResImageTexture::TYPE_INFO:
113 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResImageTexture>(resImageTexture));
114 break;
115 case ResCubeTexture::TYPE_INFO:
116 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResCubeTexture>(resImageTexture));
117 break;
118 case ResShadowTexture::TYPE_INFO:
119 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResShadowTexture>(resImageTexture));
120 break;
121 default:
122 NW_FATAL_ERROR("Unsupported texture type.\n");
123 }
124
125 return result;
126 }
127
128 /*!--------------------------------------------------------------------------*
129 @brief プロシージャルテクスチャマッパーをセットアップします。
130
131 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
132 @param[in] allocator アロケータです。
133 @param[in] graphicsFile グラフィックスファイルです。
134 *---------------------------------------------------------------------------*/
135 static Result
ResProceduralTextureMapper_Setup(ResTextureMapper resTextureMapper,os::IAllocator * allocator,ResGraphicsFile graphicsFile)136 ResProceduralTextureMapper_Setup(ResTextureMapper resTextureMapper, os::IAllocator* allocator, ResGraphicsFile graphicsFile)
137 {
138 return SetupTexture(allocator, resTextureMapper.GetTexture(), graphicsFile);
139 }
140
141 /*!--------------------------------------------------------------------------*
142 @brief ピクセルベーステクスチャマッパーの後始末をします。
143
144 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
145 *---------------------------------------------------------------------------*/
146 static void
ResPixelBasedTextureMapper_Cleanup(ResTextureMapper resTextureMapper)147 ResPixelBasedTextureMapper_Cleanup(ResTextureMapper resTextureMapper)
148 {
149 ResPixelBasedTextureMapper resPixelBasedTextureMapper =
150 ResStaticCast<ResPixelBasedTextureMapper>(resTextureMapper);
151
152 resPixelBasedTextureMapper.ResetCommand();
153
154 ResTexture resTexture = resTextureMapper.GetTexture();
155 ut::SafeCleanup(resTexture);
156 }
157
158 /*!--------------------------------------------------------------------------*
159 @brief プロシージャルテクスチャマッパーの後始末をします。
160
161 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
162 *---------------------------------------------------------------------------*/
163 static void
ResProceduralTextureMapper_Cleanup(ResTextureMapper resTextureMapper)164 ResProceduralTextureMapper_Cleanup(ResTextureMapper resTextureMapper)
165 {
166 ResTexture resTexture = resTextureMapper.GetTexture();
167 ut::SafeCleanup(resTexture);
168 }
169
170 /*!--------------------------------------------------------------------------*
171 @brief ピクセルベーステクスチャマッパーをクローンします。
172
173 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
174 @param[in] allocator アロケータです。
175 *---------------------------------------------------------------------------*/
176 static ResTextureMapper
ResPixelBasedTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper,os::IAllocator * allocator)177 ResPixelBasedTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator)
178 {
179 // この関数で確保されるメモリのサイズに変化があった場合は
180 // ResTextureMapper::GetRequiredMemorySizeForClone を修正してください。
181 ResPixelBasedTextureMapper resPixelBasedTextureMapper =
182 ResStaticCast<ResPixelBasedTextureMapper>(resTextureMapper);
183
184 void* mapperMemory = allocator->Alloc(sizeof(ResPixelBasedTextureMapperData));
185 if (mapperMemory == NULL)
186 {
187 return ResTextureMapper(NULL);
188 }
189
190 ResPixelBasedTextureMapperData* textureMapper =
191 new(mapperMemory) ResPixelBasedTextureMapperData(resPixelBasedTextureMapper.ref());
192
193 ResPixelBasedTextureMapper cloneTextureMapper = ResPixelBasedTextureMapper(textureMapper);
194
195 ResTexture resTexture = resPixelBasedTextureMapper.GetTexture();
196 if (resTexture.IsValid())
197 {
198 // リファレンステクスチャを生成してテクスチャを参照します。
199 ResTexture referenceTexture = ReferResTexture(allocator, resTexture);
200 if (referenceTexture.IsValid())
201 {
202 textureMapper->toTexture.set_ptr(referenceTexture.ptr());
203 }
204 else
205 {
206 ResPixelBasedTextureMapper_DestroyDynamic(cloneTextureMapper, allocator);
207 return ResTextureMapper(NULL);
208 }
209 }
210
211 ResStandardTextureSampler resStandardTextureSampler =
212 ResDynamicCast<ResStandardTextureSampler>(resPixelBasedTextureMapper.GetSampler());
213
214 if (resStandardTextureSampler.IsValid())
215 {
216 void* samplerMemory = allocator->Alloc(sizeof(ResStandardTextureSamplerData));
217 if (samplerMemory == NULL)
218 {
219 ResPixelBasedTextureMapper_DestroyDynamic(cloneTextureMapper, allocator);
220 return ResTextureMapper(NULL);
221 }
222
223 ResStandardTextureSamplerData* textureSampler =
224 new(samplerMemory) ResStandardTextureSamplerData(resStandardTextureSampler.ref());
225
226 textureMapper->toSampler.set_ptr(textureSampler);
227 textureSampler->toOwner.set_ptr(textureMapper);
228 }
229
230 return cloneTextureMapper;
231 }
232
233 /*!--------------------------------------------------------------------------*
234 @brief プロシージャルテクスチャマッパーをクローンします。
235
236 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
237 @param[in] allocator アロケータです。
238 *---------------------------------------------------------------------------*/
239 static ResTextureMapper
ResProceduralTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper,os::IAllocator * allocator)240 ResProceduralTextureMapper_CloneDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator)
241 {
242 // この関数で確保されるメモリのサイズに変化があった場合は
243 // ResTextureMapper::GetRequiredMemorySizeForClone を修正してください。
244 ResProceduralTextureMapper resProceduralTextureMapper =
245 ResStaticCast<ResProceduralTextureMapper>(resTextureMapper);
246
247 void* mapperMemory = allocator->Alloc(sizeof(ResProceduralTextureMapperData));
248 if (mapperMemory == NULL)
249 {
250 return ResTextureMapper(NULL);
251 }
252
253 ResProceduralTextureMapperData* textureMapper =
254 new(mapperMemory) ResProceduralTextureMapperData(resProceduralTextureMapper.ref());
255
256 ResProceduralTextureMapper cloneTextureMapper = ResProceduralTextureMapper(textureMapper);
257
258 ResTexture resTexture = resProceduralTextureMapper.GetTexture();
259 if (resTexture.IsValid())
260 {
261 // リファレンステクスチャを生成してテクスチャを参照します。
262 ResTexture referenceTexture = ReferResTexture(allocator, resTexture);
263 if (referenceTexture.IsValid())
264 {
265 textureMapper->toTexture.set_ptr(referenceTexture.ptr());
266 }
267 else
268 {
269 ResProceduralTextureMapper_DestroyDynamic(cloneTextureMapper, allocator);
270 return ResTextureMapper(NULL);
271 }
272 }
273
274 return cloneTextureMapper;
275 }
276
277 /*!--------------------------------------------------------------------------*
278 @brief ピクセルベーステクスチャマッパーを削除します。
279
280 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
281 @param[in] allocator アロケータです。
282 *---------------------------------------------------------------------------*/
283 static void
ResPixelBasedTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper,os::IAllocator * allocator)284 ResPixelBasedTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator)
285 {
286 ResPixelBasedTextureMapper resPixelBasedTextureMapper =
287 ResStaticCast<ResPixelBasedTextureMapper>(resTextureMapper);
288
289 if (resPixelBasedTextureMapper.GetSampler().IsValid())
290 {
291 allocator->Free(resPixelBasedTextureMapper.ref().toSampler.to_ptr());
292 }
293
294 if (resPixelBasedTextureMapper.GetTexture().IsValid())
295 {
296 allocator->Free(resPixelBasedTextureMapper.ref().toTexture.to_ptr());
297 }
298
299 allocator->Free(resPixelBasedTextureMapper.ptr());
300 }
301
302 /*!--------------------------------------------------------------------------*
303 @brief プロシージャルテクスチャマッパーを削除します。
304
305 @param[in] resTextureMapper 対象となるテクスチャマッパーリソースのインスタンスです。
306 @param[in] allocator アロケータです。
307 *---------------------------------------------------------------------------*/
308 static void
ResProceduralTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper,os::IAllocator * allocator)309 ResProceduralTextureMapper_DestroyDynamic(ResTextureMapper resTextureMapper, os::IAllocator* allocator)
310 {
311 ResProceduralTextureMapper resProceduralTextureMapper =
312 ResStaticCast<ResProceduralTextureMapper>(resTextureMapper);
313
314 if (resProceduralTextureMapper.GetTexture().IsValid())
315 {
316 allocator->Free(resProceduralTextureMapper.ref().toTexture.to_ptr());
317 }
318
319 allocator->Free(resProceduralTextureMapper.ptr());
320 }
321
322 //-----------------------------------------
323 ResTextureMapper
CloneDynamic(os::IAllocator * allocator)324 ResTextureMapper::CloneDynamic(os::IAllocator* allocator)
325 {
326 NW_NULL_ASSERT(allocator);
327 ResTextureMapper resTextureMapper;
328 switch ( this->ref().typeInfo )
329 {
330 case ResPixelBasedTextureMapper::TYPE_INFO:
331 {
332 resTextureMapper = s_TextureMapperCloneDynamicTable[0]( *this, allocator );
333 }
334 break;
335 case ResProceduralTextureMapper::TYPE_INFO:
336 {
337 resTextureMapper = s_TextureMapperCloneDynamicTable[1]( *this, allocator );
338 }
339 break;
340 default:
341 {
342 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
343 }
344 }
345
346 if (resTextureMapper.IsValid())
347 {
348 resTextureMapper.ref().m_DynamicAllocator = allocator;
349 }
350
351 return resTextureMapper;
352 }
353
354 //-----------------------------------------
355 void
GetMemorySizeForCloneInternal(os::MemorySizeCalculator * pSize) const356 ResTextureMapper::GetMemorySizeForCloneInternal(os::MemorySizeCalculator* pSize) const
357 {
358 os::MemorySizeCalculator& size = *pSize;
359
360 switch ( this->ref().typeInfo )
361 {
362 case res::ResPixelBasedTextureMapper::TYPE_INFO:
363 {
364 // ResPixelBasedTextureMapper_CloneDynamic
365 NW_ASSERT(ResStaticCast<ResPixelBasedTextureMapper>(*this).GetTexture().IsValid());
366 NW_ASSERT(ResDynamicCast<ResStandardTextureSampler>(ResStaticCast<ResPixelBasedTextureMapper>(*this).GetSampler()).IsValid());
367
368 size += sizeof(ResPixelBasedTextureMapperData);
369 size += sizeof(ResReferenceTextureData);
370 size += sizeof(ResStandardTextureSamplerData);
371
372 return;
373 }
374 case res::ResProceduralTextureMapper::TYPE_INFO:
375 default:
376 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
377 }
378 }
379
380 //-----------------------------------------
381 void
DestroyDynamic()382 ResTextureMapper::DestroyDynamic()
383 {
384 if ( this->ref().m_DynamicAllocator == NULL ) { return; }
385
386 switch ( this->ref().typeInfo )
387 {
388 case ResPixelBasedTextureMapper::TYPE_INFO:
389 {
390 s_TextureMapperDestroyDynamicTable[0]( *this, this->ref().m_DynamicAllocator );
391 }
392 break;
393 case ResProceduralTextureMapper::TYPE_INFO:
394 {
395 s_TextureMapperDestroyDynamicTable[1]( *this, this->ref().m_DynamicAllocator );
396 }
397 break;
398 default:
399 {
400 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
401 }
402 }
403
404 this->ref().m_DynamicAllocator = NULL;
405 }
406
407
408
409 //----------------------------------------
410 Result
Setup(os::IAllocator * allocator,ResGraphicsFile graphicsFile)411 ResTextureMapper::Setup(
412 os::IAllocator* allocator,
413 ResGraphicsFile graphicsFile
414 )
415 {
416 NW_NULL_ASSERT(allocator);
417 Result result = RESOURCE_RESULT_OK;
418
419 switch ( this->ref().typeInfo )
420 {
421 case ResPixelBasedTextureMapper::TYPE_INFO:
422 {
423 result |= s_TextureMapperSetupTable[0]( *this, allocator, graphicsFile );
424 }
425 break;
426 case ResProceduralTextureMapper::TYPE_INFO:
427 {
428 result |= s_TextureMapperSetupTable[1]( *this, allocator, graphicsFile );
429 }
430 break;
431 default:
432 {
433 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
434 }
435 }
436
437 return result;
438 }
439
440 //----------------------------------------
441 void
Cleanup()442 ResTextureMapper::Cleanup()
443 {
444 switch ( this->ref().typeInfo )
445 {
446 case ResPixelBasedTextureMapper::TYPE_INFO:
447 {
448 s_TextureMapperCleanupTable[0]( *this );
449 }
450 break;
451 case ResProceduralTextureMapper::TYPE_INFO:
452 {
453 s_TextureMapperCleanupTable[1]( *this );
454 }
455 break;
456 default:
457 {
458 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
459 }
460 }
461 }
462
463 //----------------------------------------
464 void
SetTexture(ResTexture resTexture)465 ResTextureMapper::SetTexture(ResTexture resTexture)
466 {
467 NW_ASSERT(resTexture.IsValid());
468
469 ResReferenceTexture referenceTexture = ResStaticCast<ResReferenceTexture>(this->GetTexture());
470 referenceTexture.ref().toTargetTexture.set_ptr(resTexture.Dereference().ptr());
471
472 switch ( this->ref().typeInfo )
473 {
474 case ResPixelBasedTextureMapper::TYPE_INFO:
475 {
476 ResPixelBasedTextureMapper resPixelBasedTextureMapper =
477 ResStaticCast<ResPixelBasedTextureMapper>(*this);
478 ResTexture resImageTexture = resTexture.Dereference();
479
480 switch ( resImageTexture.ref().typeInfo )
481 {
482 case ResImageTexture::TYPE_INFO:
483 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResImageTexture>(resImageTexture));
484 break;
485 case ResCubeTexture::TYPE_INFO:
486 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResCubeTexture>(resImageTexture));
487 break;
488 case ResShadowTexture::TYPE_INFO:
489 SetupTextureMapperCommand(resPixelBasedTextureMapper, ResStaticCast<ResShadowTexture>(resImageTexture));
490 break;
491 default:
492 NW_FATAL_ERROR("Unsupported texture type.\n");
493 }
494 }
495 break;
496 case ResProceduralTextureMapper::TYPE_INFO:
497 {
498 // TODO: ProceduralTextureに対応したコマンドを生成する。
499 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
500 }
501 break;
502 default:
503 {
504 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
505 }
506 }
507 }
508
509 //----------------------------------------
510 void
SetSampler(ResTextureSampler resTextureSampler)511 ResPixelBasedTextureMapper::SetSampler(ResTextureSampler resTextureSampler)
512 {
513 NW_ASSERT(resTextureSampler.IsValid());
514
515 this->ref().toSampler.set_ptr(resTextureSampler.ptr());
516
517 u32* command = this->GetCommandCache();
518
519 // BorderColorを更新する
520 NW_NULL_ASSERT(command);
521
522 switch ( resTextureSampler.ref().typeInfo )
523 {
524 case ResStandardTextureSampler::TYPE_INFO:
525 {
526 ResStandardTextureSampler resStandardTextureSampler =
527 ResStaticCast<ResStandardTextureSampler>(resTextureSampler);
528 command[2] = resStandardTextureSampler.GetBorderColor().ToPicaU32();
529 }
530 break;
531 case ResShadowTextureSampler ::TYPE_INFO:
532 {
533 // TODO: ShadowTextureSampler が実装されたら対応する。
534 }
535 break;
536 default:
537 {
538 NW_FATAL_ERROR("Unsupported sampler type.");
539 }
540 break;
541 }
542 }
543
544 /*!--------------------------------------------------------------------------*
545 @brief リソースのテクスチャを参照します。
546
547 @param[in] allocator アロケータです。
548 @param[in] resTexture オリジナルのデータです。
549 *---------------------------------------------------------------------------*/
ReferResTexture(os::IAllocator * allocator,ResTexture resTexture)550 static ResTexture ReferResTexture(
551 os::IAllocator* allocator,
552 ResTexture resTexture)
553 {
554 // この関数で確保されるメモリのサイズに変化があった場合は
555 // ResTextureMapper::GetRequiredMemorySizeForClone を修正してください。
556
557 void* textureMemory = allocator->Alloc(sizeof(ResReferenceTextureData));
558 if (textureMemory == NULL)
559 {
560 return ResTexture(NULL);
561 }
562
563 ResReferenceTextureData* texture = new(textureMemory) ResReferenceTextureData();
564 texture->typeInfo = ResReferenceTexture::TYPE_INFO;
565 texture->toName.set_ptr(NULL);
566 texture->toPath.set_ptr(NULL);
567 texture->toTargetTexture.set_ptr(NULL);
568
569 switch ( resTexture.ref().typeInfo )
570 {
571 case ResImageTexture::TYPE_INFO:
572 {
573 texture->toTargetTexture.set_ptr(resTexture.ptr());
574 }
575 break;
576 case ResCubeTexture::TYPE_INFO:
577 {
578 texture->toTargetTexture.set_ptr(resTexture.ptr());
579 }
580 break;
581 case ResReferenceTexture::TYPE_INFO:
582 {
583 ResReferenceTexture referenceTexture = ResDynamicCast<ResReferenceTexture>(resTexture);
584 texture->toTargetTexture.set_ptr(referenceTexture.GetTargetTexture().ptr());
585 }
586 break;
587 case ResProceduralTexture::TYPE_INFO:
588 {
589 texture->toTargetTexture.set_ptr(resTexture.ptr());
590 }
591 break;
592 default:
593 {
594 NW_FATAL_ERROR("Unsupported texture mapper type.\n");
595 }
596 }
597
598 return ResTexture(texture);
599 }
600
601 /*!--------------------------------------------------------------------------*
602 @brief テクスチャをセットアップします。
603
604 @param[in] allocator アロケータです。
605 @param[in] resTexture セットアップを行うテクスチャです。
606 @param[in] graphicsFile グラフィックスファイルです。
607 *---------------------------------------------------------------------------*/
SetupTexture(os::IAllocator * allocator,ResTexture resTexture,ResGraphicsFile graphicsFile)608 static Result SetupTexture(
609 os::IAllocator* allocator,
610 ResTexture resTexture,
611 ResGraphicsFile graphicsFile
612 )
613 {
614 Result result = RESOURCE_RESULT_OK;
615 ResTexture setupTexture;
616
617 bool existTexture = false;
618 if (resTexture.IsValid())
619 {
620 ResReferenceTexture refer = ResDynamicCast<ResReferenceTexture>(resTexture);
621 if (refer.IsValid())
622 {
623 if (refer.GetTargetTexture().IsValid())
624 {
625 setupTexture = refer.GetTargetTexture();
626 existTexture = true;
627 }
628 else
629 {
630 ::std::pair<ResTexture, bool> referenceResult;
631 referenceResult = GetReferenceTextureTarget(refer, graphicsFile);
632 if (referenceResult.second)
633 {
634 setupTexture = referenceResult.first;
635 existTexture = true;
636 }
637 else
638 {
639 result |= Result::MASK_FAIL_BIT;
640 result |= RESOURCE_RESULT_NOT_FOUND_TEXTURE;
641 }
642 }
643 }
644 else
645 {
646 setupTexture = resTexture;
647 existTexture = true;
648 }
649 }
650
651 if (existTexture)
652 {
653 result |= setupTexture.Setup(allocator, graphicsFile);
654 }
655
656 return result;
657 }
658
659 enum
660 {
661 HEIGHT_SHIFT = 0,
662 WIDTH_SHIFT = 16,
663 HEIGHT_MASK = 0x7FF << HEIGHT_SHIFT,
664 WIDTH_MASK = 0x7FF << WIDTH_SHIFT,
665 ADDRESS_MASK = 0x0FFFFFFF,
666 CUBE_ADDRESS_MASK = 0x003FFFFF,
667 FORMAT_SHIFT = 0,
668 FORMAT_MASK = 0xF,
669 FORMAT_ETC_SHIFT = 4,
670 FORMAT_ETC_MASK = 0x3 << FORMAT_ETC_SHIFT,
671 MIPMAP_SIZE_SHIFT = 16,
672 MIPMAP_SIZE_MASK = 0xF << MIPMAP_SIZE_SHIFT,
673 SAMPLER_TYPE_SHADOW_2D = 2,
674 SAMPLER_TYPE_SHIFT = 28,
675 SAMPLER_TYPE_MASK = 0x7 << SAMPLER_TYPE_SHIFT
676 };
677
678 /* --------------------------------------------------------------------------
679 コマンドのフォーマット
680 0 : 0x8e [3:0]format
681 1 : コマンドヘッダ
682 2 : 0x81 border_color
683 3 : コマンドヘッダ
684 4 : 0x82 [26:16]width [10:0]height
685 5 : 0x83 [5:4]etc_format|[14:12]wrap_s|[10:8]wraw_t|[1]mag_filter|[24][2]min_filter|[30:28]sampler_type
686 6 : 0x84 [27:24]min lod|[19:16]mipmap size|[12:0]lod bias
687 7 : 0x85 [27:0] addr
688 8 : 0x86 [21:0] addr(neg_x)
689 9 : 0x87 [21:0] addr(pos_y)
690 10 : 0x88 [21:0] addr(neg_y)
691 11 : 0x89 [21:0] addr(pos_z)
692 12 : 0x8a [21:0] addr(neg_z)
693 13 : 0x8b [0:0]perspectiveShadow [23:1]shadowZBias [31:24]shadowZScale
694 -------------------------------------------------------------------------- */
695 static void
SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper,ResImageTexture texture)696 SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResImageTexture texture)
697 {
698 u32* command = mapper.GetCommandCache();
699 mapper.SetCommandSizeToSend(8 * sizeof(u32));
700
701 // これから設定する箇所をリセットする
702 command[0] &= ~FORMAT_MASK; // format
703 command[3] &= ~0x0FF00000; // コマンドヘッダ
704 command[4] &= ~(HEIGHT_MASK | WIDTH_MASK); // width, height
705 command[5] &= ~(FORMAT_ETC_MASK); // etc_format
706 command[6] &= ~(MIPMAP_SIZE_MASK); // mipmap
707 command[7] &= ~ADDRESS_MASK; // address
708
709 uint texId = texture.GetTextureObject();
710 ResPixelBasedImage resImage = texture.GetImage();
711 u32 addr = resImage.GetImageAddress();
712
713 uint format = texture.GetFormatHW();
714
715 command[0] |= format & FORMAT_MASK;
716
717 // コマンドの長さを設定
718 // 0x82-0x85で 5 - 1 = 4
719 command[3] |= 4 << 20;
720 command[1] |= 0x000F0000; // glの吐くコードと同じにしてみる。
721
722 command[4] |= (texture.GetHeight() & 0x7FF) << 0;
723 command[4] |= (texture.GetWidth() & 0x7FF) << WIDTH_SHIFT;
724
725 if (format == ResImageTexture::FORMAT_HW_ETC1)
726 {
727 command[5] |= 2 << FORMAT_ETC_SHIFT;
728 }
729
730 command[6] |= ((texture.GetMipmapSize() - 1) & 0xF) << MIPMAP_SIZE_SHIFT;
731
732 command[7] |= (nngxGetPhysicalAddr( addr ) >> 3) & ADDRESS_MASK;
733 }
734
735 //---------------------------------------------------------------------------
736 //! @brief テクスチャのアドレスが GPU の制約を満たしているかどうかをチェックします。
737 //!
738 //! @param[in] texture キューブテクスチャです。
739 //!
740 //! @return 制約を満たしているならば true, 満たしていない場合は false を返します。
741 //---------------------------------------------------------------------------
742 static bool
VerifyCubeTextureAddress_(ResCubeTexture texture)743 VerifyCubeTextureAddress_( ResCubeTexture texture )
744 {
745 u32 base_addr = 0;
746 uint texId = texture.GetTextureObject();
747
748 for ( int face = 0; face < ResCubeTexture::MAX_CUBE_FACE; ++face )
749 {
750 ResPixelBasedImage resImage = texture.GetImage( static_cast<ResCubeTexture::CubeFace>( face ) );
751 u32 addr = nngxGetPhysicalAddr( resImage.GetImageAddress() );
752
753 // POSITIVE_X が必ず先頭アドレスである必要がある。全ての面のテクスチャが 32MB 境界を跨がない。
754 if (face == ResCubeTexture::CUBE_FACE_POSITIVE_X)
755 {
756 base_addr = addr;
757 }
758 else
759 {
760 if ( addr < base_addr )
761 {
762 return false;
763 }
764
765 if ( (base_addr & 0xFE000000) != (addr & 0xFE000000) )
766 {
767 return false;
768 }
769 }
770 }
771
772 return true;
773 }
774
775 //--------------------------------------------------------------------------
776 //! @brief キューブテクスチャの情報を収集してテクスチャマッパにコマンドを構築します。
777 //!
778 //! @param[in] mapper テクスチャマッパです。
779 //! @param[in] texture キューブテクスチャの情報です。
780 //---------------------------------------------------------------------------
781 static void
SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper,ResCubeTexture texture)782 SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResCubeTexture texture)
783 {
784 u32* command = mapper.GetCommandCache();
785 mapper.SetCommandSizeToSend(14 * sizeof(u32));
786
787 uint texId = texture.GetTextureObject();
788
789 uint format = texture.GetFormatHW();
790
791 // これから設定する箇所をリセットする
792 command[0] &= ~FORMAT_MASK;
793 command[3] &= ~0x0FF00000;
794 command[4] &= ~(HEIGHT_MASK | WIDTH_MASK); // width, height
795 command[5] &= ~(FORMAT_ETC_MASK); // etc_format
796 command[6] &= ~(MIPMAP_SIZE_MASK); // mipmap
797 command[7] &= ~ADDRESS_MASK; // address
798 command[8] &= ~CUBE_ADDRESS_MASK;
799 command[9] &= ~CUBE_ADDRESS_MASK;
800 command[10] &= ~CUBE_ADDRESS_MASK;
801 command[11] &= ~CUBE_ADDRESS_MASK;
802 command[12] &= ~CUBE_ADDRESS_MASK;
803
804 command[0] |= format & 0xF;
805 // コマンドの長さを調整
806 command[3] |= 9 << 20;
807
808 command[4] |= (texture.GetHeight() & 0x7FF) << 0;
809 command[4] |= (texture.GetWidth() & 0x7FF) << WIDTH_SHIFT;
810
811 if (format == ResImageTexture::FORMAT_HW_ETC1)
812 {
813 command[5] |= 2 << FORMAT_ETC_SHIFT;
814 }
815
816 NW_ASSERT( VerifyCubeTextureAddress_( texture ) );
817
818 command[6] |= ((texture.GetMipmapSize() - 1) & 0xF) << MIPMAP_SIZE_SHIFT;
819
820 for ( int face = 0; face < ResCubeTexture::MAX_CUBE_FACE; ++face )
821 {
822 ResPixelBasedImage resImage = texture.GetImage( static_cast<ResCubeTexture::CubeFace>( face ) );
823 u32 addr = resImage.GetImageAddress();
824
825 if (face == 0)
826 {
827 command[7] |= (nngxGetPhysicalAddr( addr ) >> 3) & ADDRESS_MASK;
828 }
829 else
830 {
831 command[7 + face] |= (nngxGetPhysicalAddr( addr ) >> 3) & CUBE_ADDRESS_MASK;
832 }
833 }
834 }
835
836 //--------------------------------------------------------------------------
837 //! @brief シャドウテクスチャの情報を収集してテクスチャマッパにコマンドを構築します。
838 //!
839 //! @param[in] mapper テクスチャマッパです。
840 //! @param[in] texture シャドウテクスチャの情報です。
841 //---------------------------------------------------------------------------
842 static void
SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper,ResShadowTexture texture)843 SetupTextureMapperCommand(ResPixelBasedTextureMapper mapper, ResShadowTexture texture)
844 {
845 u32* command = mapper.GetCommandCache();
846 mapper.SetCommandSizeToSend(14 * sizeof(u32));
847
848 // これから設定する箇所をリセットする
849 command[0] &= ~FORMAT_MASK; // format
850 command[3] &= ~0x0FF00000; // コマンドヘッダ
851 command[4] &= ~(HEIGHT_MASK | WIDTH_MASK); // width, height
852 command[5] &= ~(FORMAT_ETC_MASK | SAMPLER_TYPE_MASK); // etc_format
853 command[6] &= ~(MIPMAP_SIZE_MASK); // mipmap
854 command[7] &= ~ADDRESS_MASK; // address
855 command[13] = 0x0; // shadow
856
857 uint texId = texture.GetTextureObject();
858 ResPixelBasedImage resImage = texture.GetImage();
859 u32 addr = resImage.GetImageAddress();
860
861 uint format = texture.GetFormatHW();
862
863 command[0] |= format & FORMAT_MASK;
864
865 // コマンドの長さを設定
866 command[3] |= 10 << 20;
867 command[1] |= 0x000F0000; // glの吐くコードと同じにしてみる。
868
869 command[4] |= (texture.GetHeight() & 0x7FF) << 0;
870 command[4] |= (texture.GetWidth() & 0x7FF) << WIDTH_SHIFT;
871 // texture_shadow_2d
872 command[5] |= SAMPLER_TYPE_SHADOW_2D << SAMPLER_TYPE_SHIFT;
873
874 command[6] |= ((texture.GetMipmapSize() - 1) & 0xF) << MIPMAP_SIZE_SHIFT;
875
876 command[7] |= (nngxGetPhysicalAddr( addr ) >> 3) & ADDRESS_MASK;
877
878 command[13] |= ((texture.IsPerspectiveShadow() ? 0 : 1) & 0x1) << 0;
879 command[13] |= ((ut::FixedU24::Float32ToFixedU24(texture.GetShadowZBias()) >> 1) & 0x7FFFFF) << 1;
880
881 u32 scaleU32 = ((ut::Float32::Float32ToBits32(texture.GetShadowZScale()) >> 23) & 0xFF);
882 command[13] |= ((scaleU32 - 127) & 0xFF) << 24;
883 }
884
885 } /* namespace res */
886 } /* namespace gfx */
887 } /* namespace nw */
888
889