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