blob: 047691fba10d8c905d5bf66191c886aaeef0ccc2 [file] [log] [blame]
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/renderer/ProgramImpl.h"
Brandon Jones1a8a7e32014-10-01 12:49:30 -070010
11#include "common/utilities.h"
Brandon Jones1a8a7e32014-10-01 12:49:30 -070012
13namespace rx
14{
15
16namespace
17{
18
19unsigned int ParseAndStripArrayIndex(std::string* name)
20{
21 unsigned int subscript = GL_INVALID_INDEX;
22
23 // Strip any trailing array operator and retrieve the subscript
24 size_t open = name->find_last_of('[');
25 size_t close = name->find_last_of(']');
26 if (open != std::string::npos && close == name->length() - 1)
27 {
28 subscript = atoi(name->substr(open + 1).c_str());
29 name->erase(open);
30 }
31
32 return subscript;
33}
34
35}
36
Brandon Jones1a8a7e32014-10-01 12:49:30 -070037ProgramImpl::~ProgramImpl()
38{
39 // Ensure that reset was called by the inherited class during destruction
40 ASSERT(mUniformIndex.size() == 0);
41}
42
43gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
44{
45 ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
46 return mUniforms[mUniformIndex[location].index];
47}
48
49gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
50{
51 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
52 {
53 if (mUniforms[uniformIndex]->name == name)
54 {
55 return mUniforms[uniformIndex];
56 }
57 }
58
59 return NULL;
60}
61
62gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
63{
64 ASSERT(blockIndex < mUniformBlocks.size());
65 return mUniformBlocks[blockIndex];
66}
67
68GLint ProgramImpl::getUniformLocation(std::string name)
69{
70 unsigned int subscript = ParseAndStripArrayIndex(&name);
71
72 unsigned int numUniforms = mUniformIndex.size();
73 for (unsigned int location = 0; location < numUniforms; location++)
74 {
75 if (mUniformIndex[location].name == name)
76 {
77 const int index = mUniformIndex[location].index;
78 const bool isArray = mUniforms[index]->isArray();
79
80 if ((isArray && mUniformIndex[location].element == subscript) ||
81 (subscript == GL_INVALID_INDEX))
82 {
83 return location;
84 }
85 }
86 }
87
88 return -1;
89}
90
91GLuint ProgramImpl::getUniformIndex(std::string name)
92{
93 unsigned int subscript = ParseAndStripArrayIndex(&name);
94
95 // The app is not allowed to specify array indices other than 0 for arrays of basic types
96 if (subscript != 0 && subscript != GL_INVALID_INDEX)
97 {
98 return GL_INVALID_INDEX;
99 }
100
101 unsigned int numUniforms = mUniforms.size();
102 for (unsigned int index = 0; index < numUniforms; index++)
103 {
104 if (mUniforms[index]->name == name)
105 {
106 if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
107 {
108 return index;
109 }
110 }
111 }
112
113 return GL_INVALID_INDEX;
114}
115
116GLuint ProgramImpl::getUniformBlockIndex(std::string name) const
117{
118 unsigned int subscript = ParseAndStripArrayIndex(&name);
119
120 unsigned int numUniformBlocks = mUniformBlocks.size();
121 for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
122 {
123 const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
124 if (uniformBlock.name == name)
125 {
126 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
127 if (subscript == uniformBlock.elementIndex || arrayElementZero)
128 {
129 return blockIndex;
130 }
131 }
132 }
133
134 return GL_INVALID_INDEX;
135}
136
137void ProgramImpl::reset()
138{
139 SafeDeleteContainer(mUniforms);
140 mUniformIndex.clear();
141 SafeDeleteContainer(mUniformBlocks);
142 mTransformFeedbackLinkedVaryings.clear();
143}
144
145}