1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ResFragmentShader.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: 14970 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "../precompiled.h"
17 
18 #include <nw/gfx/res/gfx_ResUtil.h>
19 #include <nw/gfx/res/gfx_ResFragmentShader.h>
20 #include <nw/gfx/res/gfx_ResGraphicsFile.h>
21 
22 namespace nw {
23 namespace gfx {
24 namespace res {
25 
26 //----------------------------------------------------------------------------
27 Result
Setup(os::IAllocator * allocator,ResGraphicsFile graphicsFile)28 ResFragmentShader::Setup(os::IAllocator* allocator, ResGraphicsFile graphicsFile)
29 {
30     NW_ASSERT( this->IsValid() );
31 
32     Result result = RESOURCE_RESULT_OK;
33 
34     ResFragmentLightingTable resFragmentLightingTable = this->GetFragmentLightingTable();
35     result |= resFragmentLightingTable.Setup(allocator, graphicsFile);
36 
37     // FragmentLightingのEnableフラグとレイヤ・コンフィグに沿って参照テーブルが配置されているかチェックします。
38     if (!this->CheckFragmentShader())
39     {
40         result |= RESOURCE_RESULT_IRRELEVANT_LOCATION_LUT;
41     }
42 
43     return result;
44 }
45 
46 //----------------------------------------------------------------------------
47 Result
Setup(os::IAllocator * allocator,ResGraphicsFile graphicsFile)48 ResFragmentLightingTable::Setup(os::IAllocator* allocator, ResGraphicsFile graphicsFile)
49 {
50     NW_UNUSED_VARIABLE(allocator);
51     NW_ASSERT( this->IsValid() );
52 
53     Result result = RESOURCE_RESULT_OK;
54 
55     if (this->GetDistribution0Sampler().IsValid())
56     {
57         ResReferenceLookupTable resReferenceLut =
58             ResDynamicCast<ResReferenceLookupTable>(this->GetDistribution0Sampler().GetSampler());
59 
60         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
61 
62         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
63         {
64             result |= this->GetDistribution0Sampler().GetSampler().Setup();
65         }
66 
67         result |= referenceResult;
68     }
69 
70     if (this->GetDistribution1Sampler().IsValid())
71     {
72         ResReferenceLookupTable resReferenceLut =
73             ResDynamicCast<ResReferenceLookupTable>(this->GetDistribution1Sampler().GetSampler());
74 
75         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
76 
77         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
78         {
79             result |= this->GetDistribution1Sampler().GetSampler().Setup();
80         }
81 
82         result |= referenceResult;
83     }
84 
85     if (this->GetReflectanceRSampler().IsValid())
86     {
87         ResReferenceLookupTable resReferenceLut =
88             ResDynamicCast<ResReferenceLookupTable>(this->GetReflectanceRSampler().GetSampler());
89 
90         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
91 
92         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
93         {
94             result |= this->GetReflectanceRSampler().GetSampler().Setup();
95         }
96 
97         result |= referenceResult;
98     }
99 
100     if (this->GetReflectanceGSampler().IsValid())
101     {
102         ResReferenceLookupTable resReferenceLut =
103             ResDynamicCast<ResReferenceLookupTable>(this->GetReflectanceGSampler().GetSampler());
104 
105         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
106 
107         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
108         {
109             result |= this->GetReflectanceGSampler().GetSampler().Setup();
110         }
111 
112         result |= referenceResult;
113     }
114 
115     if (this->GetReflectanceBSampler().IsValid())
116     {
117         ResReferenceLookupTable resReferenceLut =
118             ResDynamicCast<ResReferenceLookupTable>(this->GetReflectanceBSampler().GetSampler());
119 
120         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
121 
122         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
123         {
124             result |= this->GetReflectanceBSampler().GetSampler().Setup();
125         }
126 
127         result |= referenceResult;
128     }
129 
130     if (this->GetFresnelSampler().IsValid())
131     {
132         ResReferenceLookupTable resReferenceLut =
133             ResDynamicCast<ResReferenceLookupTable>(this->GetFresnelSampler().GetSampler());
134 
135         Result referenceResult = SetupReferenceLut(resReferenceLut, graphicsFile);
136 
137         if ((referenceResult.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) == 0)
138         {
139             result |= this->GetFresnelSampler().GetSampler().Setup();
140         }
141 
142         result |= referenceResult;
143     }
144 
145     return result;
146 }
147 
148 //----------------------------------------
149 bool
CheckFragmentShader()150 ResFragmentShader::CheckFragmentShader()
151 {
152     bool isExisted = true;
153 
154     ResFragmentLighting fragmentLighting = this->GetFragmentLighting();
155     ResFragmentLightingTable fragmentLightingTable = this->GetFragmentLightingTable();
156 
157     s32 flags = fragmentLighting.GetFlags();
158     if ( ut::CheckFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION0_ENABLED) &&
159         (!fragmentLightingTable.GetDistribution0Sampler().IsValid() || !fragmentLightingTable.GetDistribution0Sampler().GetSampler().IsValid()))
160     {
161         flags = ut::DisableFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION0_ENABLED);
162         NW_WARNING(false, "Distribution0 is enable, but LUT is not found.");
163         isExisted = false;
164     }
165 
166     if ( ut::CheckFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION1_ENABLED) &&
167         (!fragmentLightingTable.GetDistribution1Sampler().IsValid() || !fragmentLightingTable.GetDistribution1Sampler().GetSampler().IsValid()))
168     {
169         flags = ut::DisableFlag(flags, ResFragmentLightingData::FLAG_DISTRIBUTION1_ENABLED);
170         NW_WARNING(false, "Distribution1 is enable, but LUT is not found.");
171         isExisted = false;
172     }
173 
174     if ( fragmentLighting.GetFresnelConfig() != ResFragmentLighting::CONFIG_NO_FRESNEL &&
175         (!fragmentLightingTable.GetFresnelSampler().IsValid() || !fragmentLightingTable.GetFresnelSampler().GetSampler().IsValid()))
176     {
177         fragmentLighting.SetFresnelConfig(ResFragmentLighting::CONFIG_NO_FRESNEL);
178         NW_WARNING(false, "Fresnel is enable, but LUT is not found.");
179         isExisted = false;
180     }
181 
182     if ( ut::CheckFlag(flags, ResFragmentLightingData::FLAG_REFLECTION_ENABLED) )
183     {
184         ResFragmentLighting::ConfigDetail config = ResFragmentLighting::ToConfigDetail(fragmentLighting.GetLayerConfig());
185 
186         bool invalid = false;
187 
188         if ( ut::CheckFlag(config, ResFragmentLighting::LUT_RR) &&
189             (!fragmentLightingTable.GetReflectanceRSampler().IsValid() || !fragmentLightingTable.GetReflectanceRSampler().GetSampler().IsValid()))
190         {
191             invalid = true;
192         }
193 
194         if ( ut::CheckFlag(config, ResFragmentLighting::LUT_RG) &&
195             (!fragmentLightingTable.GetReflectanceGSampler().IsValid() || !fragmentLightingTable.GetReflectanceGSampler().GetSampler().IsValid()))
196         {
197             invalid = true;
198         }
199 
200         if ( ut::CheckFlag(config, ResFragmentLighting::LUT_RB) &&
201             (!fragmentLightingTable.GetReflectanceBSampler().IsValid() || !fragmentLightingTable.GetReflectanceBSampler().GetSampler().IsValid()))
202         {
203             invalid = true;
204         }
205 
206         if ( invalid )
207         {
208             flags = ut::DisableFlag(flags, ResFragmentLightingData::FLAG_REFLECTION_ENABLED);
209             NW_WARNING(false, "Relection is enable, but LUT is not found.\n");
210             isExisted = false;
211         }
212     }
213     fragmentLighting.SetFlags(flags);
214     return isExisted;
215 }
216 
217 //----------------------------------------------------------------------------
218 void
Cleanup()219 ResFragmentShader::Cleanup()
220 {
221     ut::SafeCleanup(this->GetFragmentLightingTable());
222 }
223 
224 //----------------------------------------------------------------------------
225 void
Cleanup()226 ResFragmentLightingTable::Cleanup()
227 {
228     ut::SafeCleanup(this->GetReflectanceRSampler());
229     ut::SafeCleanup(this->GetReflectanceGSampler());
230     ut::SafeCleanup(this->GetReflectanceBSampler());
231     ut::SafeCleanup(this->GetDistribution0Sampler());
232     ut::SafeCleanup(this->GetDistribution1Sampler());
233     ut::SafeCleanup(this->GetFresnelSampler());
234 }
235 
236 } /* namespace res */
237 } /* namespace gfx */
238 } /* namespace nw */
239 
240