1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ShaderProgram.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: 24382 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/gfx/gfx_ShaderProgram.h>
19 
20 #include <nw/os/os_Memory.h>
21 #include <nw/ut/ut_Foreach.h>
22 #include <nw/gfx/gfx_ShaderBinaryInfo.h>
23 
24 namespace nw
25 {
26 namespace gfx
27 {
28 
29 //----------------------------------------
ShaderProgram(os::IAllocator * allocator)30 ShaderProgram::ShaderProgram(os::IAllocator* allocator)
31 : GfxObject(allocator),
32 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
33   m_UniformLocation(NULL),
34 #endif
35   m_ProgramObject(0),
36   m_GeometryShaderMode(GEOMETRY_SHADER_MODE_UNINITIALIZED)
37 {
38     const u32 REG_VERTEX_UNIFORM_BOOL = 0x2B0;
39     const u32 REG_GEOMETRY_UNIFORM_BOOL = 0x280;
40     const u32 REG_GEOMETRY_DISABLE = 0x244;
41 
42     const u32 HEADER_VERTEX   = internal::MakeCommandHeader(REG_VERTEX_UNIFORM_BOOL, 5, true, 0xF);
43     const u32 HEADER_GEOMETRY = internal::MakeCommandHeader(REG_GEOMETRY_UNIFORM_BOOL, 5, true, 0xF);
44     const u32 HEADER_DISABLE_GEOMETRY = internal::MakeCommandHeader(REG_GEOMETRY_DISABLE, 1, false, 0x1);
45 
46     m_VertexIntUniforms[0] = 0x7fff0000; // b0-b15
47     m_VertexIntUniforms[1] = HEADER_VERTEX,
48     m_VertexIntUniforms[2] = 0x00000000; // i0
49     m_VertexIntUniforms[3] = 0x00000000; // i1
50     m_VertexIntUniforms[4] = 0x00000000; // i2
51     m_VertexIntUniforms[5] = 0x00000000; // i3
52 
53     m_GeometryIntUniforms[0] = 0x7fff0000; // b0-b15
54     m_GeometryIntUniforms[1] = HEADER_GEOMETRY,
55     m_GeometryIntUniforms[2] = 0x00000000; // i0
56     m_GeometryIntUniforms[3] = 0x00000000; // i1
57     m_GeometryIntUniforms[4] = 0x00000000; // i2
58     m_GeometryIntUniforms[5] = 0x00000000; // i3
59 
60     m_DisableGeometry[0] = 0;
61     m_DisableGeometry[1] = HEADER_DISABLE_GEOMETRY;
62 }
63 
64 //----------------------------------------
~ShaderProgram()65 ShaderProgram::~ShaderProgram()
66 {
67 }
68 
69 //----------------------------------------
70 void
ActivateDescription(ResShaderProgramDescription shaderProgramDescription)71 ShaderProgram::ActivateDescription(ResShaderProgramDescription shaderProgramDescription)
72 {
73     // まずジオメトリシェーダのモード切替。
74     ResBinaryShader shader = ResBinaryShader( shaderProgramDescription.GetOwnerShaderData() );
75     bool hasGeometry = (shaderProgramDescription.GetGeometryShaderIndex() >= 0);
76 
77     bool skipShaderBinary = false;
78     bool skipShaderMode   = false;
79 
80     if ( m_Description.IsValid() )
81     {
82         bool hasGeometryPrev = (m_Description.GetGeometryShaderIndex() >= 0);
83         if ( hasGeometry == hasGeometryPrev )
84         {
85             skipShaderMode = true;
86         }
87 
88         ResBinaryShader shaderPrev = ResBinaryShader( m_Description.GetOwnerShaderData() );
89         if ( shader == shaderPrev )
90         {
91             skipShaderBinary = true;
92         }
93     }
94 
95     if ( ! skipShaderMode )
96     {
97         ActivateShaderProgramMode( hasGeometry );
98     }
99 
100     if ( ! skipShaderBinary )
101     {
102         NW_NULL_ASSERT( shader.ref().m_CommandCache );
103         internal::NWUseCmdlist( shader.ref().m_CommandCache, shader.ref().m_CommandCacheSize );
104     }
105 
106     NW_NULL_ASSERT( shaderProgramDescription.ref().m_CommandCache );
107     internal::NWUseCmdlist( shaderProgramDescription.ref().m_CommandCache, shaderProgramDescription.ref().m_CommandCacheSize );
108 
109 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
110     m_UniformLocation = static_cast<ShaderUniformLocation*>(shaderProgramDescription.GetUniformLocation());
111     m_ProgramObject = shaderProgramDescription.GetProgramObject();
112 #endif
113 
114     const ShaderBinaryInfo* shaderBinaryInfo = shader.GetShaderBinaryInfo();
115 
116     m_VertexIntUniforms[0]       |= shaderBinaryInfo->GetBoolConstant( shaderProgramDescription.GetVertexShaderIndex() );
117 
118     if ( hasGeometry )
119     {
120         m_GeometryIntUniforms[0] |= shaderBinaryInfo->GetBoolConstant( shaderProgramDescription.GetGeometryShaderIndex() );
121     }
122 
123     m_Description = shaderProgramDescription;
124 }
125 
126 //----------------------------------------
127 void
ActivateShaderProgramMode(bool useGeometry)128 ShaderProgram::ActivateShaderProgramMode(bool useGeometry)
129 {
130     nw::gfx::internal::SetupShaderProgramMode( useGeometry );
131 
132     m_GeometryShaderMode = useGeometry ? GEOMETRY_SHADER_MODE_USED : GEOMETRY_SHADER_MODE_NONE;
133     m_DisableGeometry[0] = useGeometry ? 1 : 0;
134 }
135 
136 } // namespace gfx
137 } // namespace nw
138