1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ShaderProgram.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 
20 #include <nw/gfx/gfx_ShaderProgram.h>
21 
22 #include <nw/os/os_Memory.h>
23 #include <nw/ut/ut_Foreach.h>
24 #include <nw/gfx/gfx_ShaderBinaryInfo.h>
25 
26 namespace nw
27 {
28 namespace gfx
29 {
30 
31 //----------------------------------------
ShaderProgram(os::IAllocator * allocator)32 ShaderProgram::ShaderProgram(os::IAllocator* allocator)
33 : GfxObject(allocator),
34 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
35   m_UniformLocation(NULL),
36 #endif
37   m_ProgramObject(0),
38   m_GeometryShaderMode(GEOMETRY_SHADER_MODE_UNINITIALIZED)
39 {
40     const u32 REG_VERTEX_UNIFORM_BOOL = 0x2B0;
41     const u32 REG_GEOMETRY_UNIFORM_BOOL = 0x280;
42     const u32 REG_GEOMETRY_DISABLE = 0x244;
43 
44     const u32 HEADER_VERTEX   = internal::MakeCommandHeader(REG_VERTEX_UNIFORM_BOOL, 5, true, 0xF);
45     const u32 HEADER_GEOMETRY = internal::MakeCommandHeader(REG_GEOMETRY_UNIFORM_BOOL, 5, true, 0xF);
46     const u32 HEADER_DISABLE_GEOMETRY = internal::MakeCommandHeader(REG_GEOMETRY_DISABLE, 1, false, 0x1);
47 
48     m_VertexIntUniforms[0] = 0x7fff0000; // b0-b15
49     m_VertexIntUniforms[1] = HEADER_VERTEX,
50     m_VertexIntUniforms[2] = 0x00000000; // i0
51     m_VertexIntUniforms[3] = 0x00000000; // i1
52     m_VertexIntUniforms[4] = 0x00000000; // i2
53     m_VertexIntUniforms[5] = 0x00000000; // i3
54 
55     m_GeometryIntUniforms[0] = 0x7fff0000; // b0-b15
56     m_GeometryIntUniforms[1] = HEADER_GEOMETRY,
57     m_GeometryIntUniforms[2] = 0x00000000; // i0
58     m_GeometryIntUniforms[3] = 0x00000000; // i1
59     m_GeometryIntUniforms[4] = 0x00000000; // i2
60     m_GeometryIntUniforms[5] = 0x00000000; // i3
61 
62     m_DisableGeometry[0] = 0;
63     m_DisableGeometry[1] = HEADER_DISABLE_GEOMETRY;
64 }
65 
66 //----------------------------------------
~ShaderProgram()67 ShaderProgram::~ShaderProgram()
68 {
69 }
70 
71 //----------------------------------------
72 void
ActivateDescription(ResShaderProgramDescription shaderProgramDescription)73 ShaderProgram::ActivateDescription(ResShaderProgramDescription shaderProgramDescription)
74 {
75     // まずジオメトリシェーダのモード切替。
76     ResBinaryShader shader = ResBinaryShader( shaderProgramDescription.GetOwnerShaderData() );
77     bool hasGeometry = (shaderProgramDescription.GetGeometryShaderIndex() >= 0);
78 
79     bool skipShaderBinary = false;
80     bool skipShaderMode   = false;
81 
82     if ( m_Description.IsValid() )
83     {
84         bool hasGeometryPrev = (m_Description.GetGeometryShaderIndex() >= 0);
85         if ( hasGeometry == hasGeometryPrev )
86         {
87             skipShaderMode = true;
88         }
89 
90         ResBinaryShader shaderPrev = ResBinaryShader( m_Description.GetOwnerShaderData() );
91         if ( shader == shaderPrev )
92         {
93             skipShaderBinary = true;
94         }
95     }
96 
97     if ( ! skipShaderMode )
98     {
99         ActivateShaderProgramMode( hasGeometry );
100     }
101 
102     if ( ! skipShaderBinary )
103     {
104         NW_NULL_ASSERT( shader.ref().m_CommandCache );
105         internal::NWUseCmdlist( shader.ref().m_CommandCache, shader.ref().m_CommandCacheSize );
106     }
107 
108     NW_NULL_ASSERT( shaderProgramDescription.ref().m_CommandCache );
109     internal::NWUseCmdlist( shaderProgramDescription.ref().m_CommandCache, shaderProgramDescription.ref().m_CommandCacheSize );
110 
111 #if defined(NW_GFX_PROGRAM_OBJECT_ENABLED)
112     m_UniformLocation = static_cast<ShaderUniformLocation*>(shaderProgramDescription.GetUniformLocation());
113     m_ProgramObject = shaderProgramDescription.GetProgramObject();
114 #endif
115 
116     const ShaderBinaryInfo* shaderBinaryInfo = shader.GetShaderBinaryInfo();
117 
118     m_VertexIntUniforms[0]       |= shaderBinaryInfo->GetBoolConstant( shaderProgramDescription.GetVertexShaderIndex() );
119 
120     if ( hasGeometry )
121     {
122         m_GeometryIntUniforms[0] |= shaderBinaryInfo->GetBoolConstant( shaderProgramDescription.GetGeometryShaderIndex() );
123     }
124 
125     m_Description = shaderProgramDescription;
126 }
127 
128 //----------------------------------------
129 void
ActivateShaderProgramMode(bool useGeometry)130 ShaderProgram::ActivateShaderProgramMode(bool useGeometry)
131 {
132     nw::gfx::internal::SetupShaderProgramMode( useGeometry );
133 
134     m_GeometryShaderMode = useGeometry ? GEOMETRY_SHADER_MODE_USED : GEOMETRY_SHADER_MODE_NONE;
135     m_DisableGeometry[0] = useGeometry ? 1 : 0;
136 }
137 
138 } // namespace gfx
139 } // namespace nw
140