blob: b0267ae2fd00c95abd012f3ee40a8ec1d64848b1 [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
Geoff Lang7dd2e102014-11-10 15:19:26 -050016LinkResult::LinkResult(bool linkSuccess, const gl::Error &error)
17 : linkSuccess(linkSuccess),
18 error(error)
19{
20}
21
Brandon Jones1a8a7e32014-10-01 12:49:30 -070022ProgramImpl::~ProgramImpl()
23{
24 // Ensure that reset was called by the inherited class during destruction
25 ASSERT(mUniformIndex.size() == 0);
26}
27
28gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
29{
30 ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
31 return mUniforms[mUniformIndex[location].index];
32}
33
34gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
35{
36 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
37 {
38 if (mUniforms[uniformIndex]->name == name)
39 {
40 return mUniforms[uniformIndex];
41 }
42 }
43
44 return NULL;
45}
46
47gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
48{
49 ASSERT(blockIndex < mUniformBlocks.size());
50 return mUniformBlocks[blockIndex];
51}
52
Geoff Langcfaeaa92015-04-14 13:41:02 -040053GLint ProgramImpl::getUniformLocation(const std::string &name) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -070054{
Geoff Langcfaeaa92015-04-14 13:41:02 -040055 size_t subscript = GL_INVALID_INDEX;
56 std::string baseName = gl::ParseUniformName(name, &subscript);
Brandon Jones1a8a7e32014-10-01 12:49:30 -070057
58 unsigned int numUniforms = mUniformIndex.size();
59 for (unsigned int location = 0; location < numUniforms; location++)
60 {
Geoff Langcfaeaa92015-04-14 13:41:02 -040061 if (mUniformIndex[location].name == baseName)
Brandon Jones1a8a7e32014-10-01 12:49:30 -070062 {
63 const int index = mUniformIndex[location].index;
64 const bool isArray = mUniforms[index]->isArray();
65
66 if ((isArray && mUniformIndex[location].element == subscript) ||
67 (subscript == GL_INVALID_INDEX))
68 {
69 return location;
70 }
71 }
72 }
73
74 return -1;
75}
76
Geoff Langcfaeaa92015-04-14 13:41:02 -040077GLuint ProgramImpl::getUniformIndex(const std::string &name) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -070078{
Geoff Langcfaeaa92015-04-14 13:41:02 -040079 size_t subscript = GL_INVALID_INDEX;
80 std::string baseName = gl::ParseUniformName(name, &subscript);
Brandon Jones1a8a7e32014-10-01 12:49:30 -070081
82 // The app is not allowed to specify array indices other than 0 for arrays of basic types
83 if (subscript != 0 && subscript != GL_INVALID_INDEX)
84 {
85 return GL_INVALID_INDEX;
86 }
87
88 unsigned int numUniforms = mUniforms.size();
89 for (unsigned int index = 0; index < numUniforms; index++)
90 {
Geoff Langcfaeaa92015-04-14 13:41:02 -040091 if (mUniforms[index]->name == baseName)
Brandon Jones1a8a7e32014-10-01 12:49:30 -070092 {
93 if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
94 {
95 return index;
96 }
97 }
98 }
99
100 return GL_INVALID_INDEX;
101}
102
Geoff Langcfaeaa92015-04-14 13:41:02 -0400103GLuint ProgramImpl::getUniformBlockIndex(const std::string &name) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700104{
Geoff Langcfaeaa92015-04-14 13:41:02 -0400105 size_t subscript = GL_INVALID_INDEX;
106 std::string baseName = gl::ParseUniformName(name, &subscript);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700107
108 unsigned int numUniformBlocks = mUniformBlocks.size();
109 for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
110 {
111 const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
Geoff Langcfaeaa92015-04-14 13:41:02 -0400112 if (uniformBlock.name == baseName)
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700113 {
114 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
115 if (subscript == uniformBlock.elementIndex || arrayElementZero)
116 {
117 return blockIndex;
118 }
119 }
120 }
121
122 return GL_INVALID_INDEX;
123}
124
125void ProgramImpl::reset()
126{
Jamie Madill437d2662014-12-05 14:23:35 -0500127 std::fill(mSemanticIndex, mSemanticIndex + ArraySize(mSemanticIndex), -1);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700128 SafeDeleteContainer(mUniforms);
129 mUniformIndex.clear();
130 SafeDeleteContainer(mUniformBlocks);
131 mTransformFeedbackLinkedVaryings.clear();
132}
133
Jamie Madill3da79b72015-04-27 11:09:17 -0400134void ProgramImpl::setShaderAttribute(size_t index, const sh::Attribute &attrib)
135{
136 if (mShaderAttributes.size() <= index)
137 {
138 mShaderAttributes.resize(index + 1);
139 }
140 mShaderAttributes[index] = attrib;
141}
142
143void ProgramImpl::setShaderAttribute(size_t index, GLenum type, GLenum precision, const std::string &name, GLint size, int location)
144{
145 if (mShaderAttributes.size() <= index)
146 {
147 mShaderAttributes.resize(index + 1);
148 }
149 mShaderAttributes[index].type = type;
150 mShaderAttributes[index].precision = precision;
151 mShaderAttributes[index].name = name;
152 mShaderAttributes[index].arraySize = size;
153 mShaderAttributes[index].location = location;
154}
155
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700156}