blob: fa4bf717f622bc5b57808cc59847045d7426a677 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 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// TextureGL.cpp: Implements the class methods for TextureGL.
8
9#include "libANGLE/renderer/gl/TextureGL.h"
10
11#include "common/debug.h"
Geoff Langc05f7062015-03-10 09:50:57 -070012#include "common/utilities.h"
Jamie Madill67102f02015-03-16 10:41:42 -040013#include "libANGLE/State.h"
Geoff Langc05f7062015-03-10 09:50:57 -070014#include "libANGLE/angletypes.h"
15#include "libANGLE/formatutils.h"
16#include "libANGLE/renderer/gl/BufferGL.h"
Geoff Langfbfa47c2015-03-31 11:26:00 -040017#include "libANGLE/renderer/gl/FramebufferGL.h"
Geoff Langc05f7062015-03-10 09:50:57 -070018#include "libANGLE/renderer/gl/FunctionsGL.h"
19#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Lang14389cc2015-07-23 10:57:20 -040020#include "libANGLE/renderer/gl/WorkaroundsGL.h"
Geoff Langfd216c42015-05-27 16:12:30 -040021#include "libANGLE/renderer/gl/formatutilsgl.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050022
23namespace rx
24{
25
Geoff Langc05f7062015-03-10 09:50:57 -070026static void SetUnpackStateForTexImage(StateManagerGL *stateManager, const gl::PixelUnpackState &unpack)
27{
28 const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
29 if (unpackBuffer != nullptr)
30 {
31 UNIMPLEMENTED();
32 }
Geoff Lang5ec53c82015-06-05 16:32:14 -040033 stateManager->setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows,
34 unpack.skipPixels, unpack.imageHeight, unpack.skipImages);
Geoff Langc05f7062015-03-10 09:50:57 -070035}
36
37static bool UseTexImage2D(GLenum textureType)
38{
39 return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP;
40}
41
42static bool UseTexImage3D(GLenum textureType)
43{
44 return textureType == GL_TEXTURE_2D_ARRAY || textureType == GL_TEXTURE_3D;
45}
46
Geoff Lang968992e2015-03-17 18:01:49 -040047static bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget)
Geoff Langc05f7062015-03-10 09:50:57 -070048{
49 if (textureType != GL_TEXTURE_CUBE_MAP)
50 {
51 return textureType == textureTarget;
52 }
53 else
54 {
Geoff Langfb2a5592015-03-20 11:25:37 -040055 return gl::IsCubeMapTextureTarget(textureTarget);
Geoff Langc05f7062015-03-10 09:50:57 -070056 }
57}
58
Geoff Lang14389cc2015-07-23 10:57:20 -040059TextureGL::TextureGL(GLenum type,
60 const FunctionsGL *functions,
61 const WorkaroundsGL &workarounds,
62 StateManagerGL *stateManager)
Geoff Langc05f7062015-03-10 09:50:57 -070063 : TextureImpl(),
64 mTextureType(type),
65 mFunctions(functions),
Geoff Lang14389cc2015-07-23 10:57:20 -040066 mWorkarounds(workarounds),
Geoff Langc05f7062015-03-10 09:50:57 -070067 mStateManager(stateManager),
68 mAppliedSamplerState(),
69 mTextureID(0)
70{
71 ASSERT(mFunctions);
72 ASSERT(mStateManager);
73
74 mFunctions->genTextures(1, &mTextureID);
Geoff Lang90d98af2015-05-26 16:41:38 -040075 mStateManager->bindTexture(mTextureType, mTextureID);
Geoff Langc05f7062015-03-10 09:50:57 -070076}
Geoff Langf9a6f082015-01-22 13:32:49 -050077
78TextureGL::~TextureGL()
Geoff Langc05f7062015-03-10 09:50:57 -070079{
Geoff Lang1eb708e2015-05-04 14:58:23 -040080 mStateManager->deleteTexture(mTextureID);
81 mTextureID = 0;
Geoff Langc05f7062015-03-10 09:50:57 -070082}
Geoff Langf9a6f082015-01-22 13:32:49 -050083
84void TextureGL::setUsage(GLenum usage)
85{
Geoff Langc05f7062015-03-10 09:50:57 -070086 // GL_ANGLE_texture_usage not implemented for desktop GL
87 UNREACHABLE();
Geoff Langf9a6f082015-01-22 13:32:49 -050088}
89
90gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
91 const gl::PixelUnpackState &unpack, const uint8_t *pixels)
92{
Geoff Langfb2a5592015-03-20 11:25:37 -040093 UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings.
Geoff Lang968992e2015-03-17 18:01:49 -040094 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -070095
96 SetUnpackStateForTexImage(mStateManager, unpack);
97
Geoff Lang23a2ae02015-07-28 12:42:52 -040098 nativegl::TexImageFormat texImageFormat =
99 nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type);
Geoff Langfd216c42015-05-27 16:12:30 -0400100
Geoff Langc05f7062015-03-10 09:50:57 -0700101 mStateManager->bindTexture(mTextureType, mTextureID);
102 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400103 {
Geoff Langc05f7062015-03-10 09:50:57 -0700104 ASSERT(size.depth == 1);
Geoff Lang23a2ae02015-07-28 12:42:52 -0400105 mFunctions->texImage2D(target, level, texImageFormat.internalFormat, size.width,
106 size.height, 0, texImageFormat.format, texImageFormat.type, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700107 }
108 else if (UseTexImage3D(mTextureType))
109 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400110 mFunctions->texImage3D(target, level, texImageFormat.internalFormat, size.width,
111 size.height, size.depth, 0, texImageFormat.format,
112 texImageFormat.type, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700113 }
114 else
115 {
116 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400117 }
118
Geoff Langc05f7062015-03-10 09:50:57 -0700119 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500120}
121
122gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
123 const gl::PixelUnpackState &unpack, const uint8_t *pixels)
124{
Geoff Lang968992e2015-03-17 18:01:49 -0400125 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700126
127 SetUnpackStateForTexImage(mStateManager, unpack);
128
Geoff Lang23a2ae02015-07-28 12:42:52 -0400129 nativegl::TexSubImageFormat texSubImageFormat =
130 nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
131
Geoff Langc05f7062015-03-10 09:50:57 -0700132 mStateManager->bindTexture(mTextureType, mTextureID);
133 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400134 {
Geoff Langc05f7062015-03-10 09:50:57 -0700135 ASSERT(area.z == 0 && area.depth == 1);
Geoff Lang23a2ae02015-07-28 12:42:52 -0400136 mFunctions->texSubImage2D(target, level, area.x, area.y, area.width, area.height,
137 texSubImageFormat.format, texSubImageFormat.type, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700138 }
139 else if (UseTexImage3D(mTextureType))
140 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400141 mFunctions->texSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height,
142 area.depth, texSubImageFormat.format, texSubImageFormat.type,
143 pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700144 }
145 else
146 {
147 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400148 }
149
Geoff Langc05f7062015-03-10 09:50:57 -0700150 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500151}
152
153gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
Geoff Lang8509d862015-05-20 14:06:13 -0400154 const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
Geoff Langf9a6f082015-01-22 13:32:49 -0500155{
Geoff Lang968992e2015-03-17 18:01:49 -0400156 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700157
158 SetUnpackStateForTexImage(mStateManager, unpack);
159
Geoff Lang23a2ae02015-07-28 12:42:52 -0400160 nativegl::CompressedTexImageFormat compressedTexImageFormat =
161 nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat);
Geoff Langfd216c42015-05-27 16:12:30 -0400162
Geoff Langc05f7062015-03-10 09:50:57 -0700163 mStateManager->bindTexture(mTextureType, mTextureID);
164 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400165 {
Geoff Langc05f7062015-03-10 09:50:57 -0700166 ASSERT(size.depth == 1);
Geoff Lang23a2ae02015-07-28 12:42:52 -0400167 mFunctions->compressedTexImage2D(target, level, compressedTexImageFormat.internalFormat,
168 size.width, size.height, 0, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700169 }
170 else if (UseTexImage3D(mTextureType))
171 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400172 mFunctions->compressedTexImage3D(target, level, compressedTexImageFormat.internalFormat,
173 size.width, size.height, size.depth, 0, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700174 }
175 else
176 {
177 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400178 }
179
Geoff Langc05f7062015-03-10 09:50:57 -0700180 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500181}
182
183gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
Geoff Lang8509d862015-05-20 14:06:13 -0400184 const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
Geoff Langf9a6f082015-01-22 13:32:49 -0500185{
Geoff Lang968992e2015-03-17 18:01:49 -0400186 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700187
188 SetUnpackStateForTexImage(mStateManager, unpack);
189
Geoff Lang23a2ae02015-07-28 12:42:52 -0400190 nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
191 nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format);
192
Geoff Langc05f7062015-03-10 09:50:57 -0700193 mStateManager->bindTexture(mTextureType, mTextureID);
194 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400195 {
Geoff Langc05f7062015-03-10 09:50:57 -0700196 ASSERT(area.z == 0 && area.depth == 1);
Geoff Lang14389cc2015-07-23 10:57:20 -0400197 mFunctions->compressedTexSubImage2D(target, level, area.x, area.y, area.width, area.height,
Geoff Lang23a2ae02015-07-28 12:42:52 -0400198 compressedTexSubImageFormat.format, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700199 }
200 else if (UseTexImage3D(mTextureType))
201 {
Geoff Lang14389cc2015-07-23 10:57:20 -0400202 mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width,
Geoff Lang23a2ae02015-07-28 12:42:52 -0400203 area.height, area.depth,
204 compressedTexSubImageFormat.format, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700205 }
206 else
207 {
208 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400209 }
210
Geoff Langc05f7062015-03-10 09:50:57 -0700211 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500212}
213
214gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
215 const gl::Framebuffer *source)
216{
Geoff Langfbfa47c2015-03-31 11:26:00 -0400217 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
218
219 mStateManager->bindTexture(mTextureType, mTextureID);
220 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
221
Geoff Lang23a2ae02015-07-28 12:42:52 -0400222 nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat(
223 mFunctions, mWorkarounds, internalFormat, source->getImplementationColorReadType());
224
Geoff Langfbfa47c2015-03-31 11:26:00 -0400225 if (UseTexImage2D(mTextureType))
226 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400227 mFunctions->copyTexImage2D(target, level, copyTexImageFormat.internalFormat, sourceArea.x,
228 sourceArea.y, sourceArea.width, sourceArea.height, 0);
Geoff Langfbfa47c2015-03-31 11:26:00 -0400229 }
230 else
231 {
232 UNREACHABLE();
233 }
234
235 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500236}
237
238gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
239 const gl::Framebuffer *source)
240{
Geoff Langfbfa47c2015-03-31 11:26:00 -0400241 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
242
243 mStateManager->bindTexture(mTextureType, mTextureID);
244 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
245
246 if (UseTexImage2D(mTextureType))
247 {
248 ASSERT(destOffset.z == 0);
249 mFunctions->copyTexSubImage2D(target, level, destOffset.x, destOffset.y,
250 sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
251 }
252 else if (UseTexImage3D(mTextureType))
253 {
254 mFunctions->copyTexSubImage3D(target, level, destOffset.x, destOffset.y, destOffset.z,
255 sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
256 }
257 else
258 {
259 UNREACHABLE();
260 }
261
262 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500263}
264
265gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
266{
Geoff Langc05f7062015-03-10 09:50:57 -0700267 // TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the
268 // ARB_texture_storage extension is not available.
269
Geoff Lang23a2ae02015-07-28 12:42:52 -0400270 nativegl::TexStorageFormat texStorageFormat =
271 nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat);
Geoff Langfd216c42015-05-27 16:12:30 -0400272
Geoff Langc05f7062015-03-10 09:50:57 -0700273 mStateManager->bindTexture(mTextureType, mTextureID);
274 if (UseTexImage2D(mTextureType))
275 {
276 ASSERT(size.depth == 1);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400277 if (mFunctions->texStorage2D)
278 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400279 mFunctions->texStorage2D(target, levels, texStorageFormat.internalFormat, size.width,
280 size.height);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400281 }
282 else
283 {
284 // Make sure no pixel unpack buffer is bound
285 mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
286
287 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
288
289 // Internal format must be sized
290 ASSERT(internalFormatInfo.pixelBytes != 0);
291
292 for (size_t level = 0; level < levels; level++)
293 {
294 gl::Extents levelSize(std::max(size.width >> level, 1),
295 std::max(size.height >> level, 1),
296 1);
297
298 if (mTextureType == GL_TEXTURE_2D)
299 {
Geoff Lang42c98f62015-05-20 14:09:25 -0400300 if (internalFormatInfo.compressed)
301 {
302 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
Geoff Lang23a2ae02015-07-28 12:42:52 -0400303 mFunctions->compressedTexImage2D(
304 target, level, texStorageFormat.internalFormat, levelSize.width,
305 levelSize.height, 0, dataSize, nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400306 }
307 else
308 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400309 mFunctions->texImage2D(target, level, texStorageFormat.internalFormat,
310 levelSize.width, levelSize.height, 0,
311 internalFormatInfo.format, internalFormatInfo.type,
312 nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400313 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400314 }
315 else if (mTextureType == GL_TEXTURE_CUBE_MAP)
316 {
317 for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++)
318 {
Geoff Lang42c98f62015-05-20 14:09:25 -0400319 if (internalFormatInfo.compressed)
320 {
321 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
Geoff Lang23a2ae02015-07-28 12:42:52 -0400322 mFunctions->compressedTexImage2D(
323 face, level, texStorageFormat.internalFormat, levelSize.width,
324 levelSize.height, 0, dataSize, nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400325 }
326 else
327 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400328 mFunctions->texImage2D(face, level, texStorageFormat.internalFormat,
329 levelSize.width, levelSize.height, 0,
330 internalFormatInfo.format,
331 internalFormatInfo.type, nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400332 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400333 }
334 }
335 else
336 {
337 UNREACHABLE();
338 }
339 }
340 }
Geoff Langc05f7062015-03-10 09:50:57 -0700341 }
342 else if (UseTexImage3D(mTextureType))
343 {
Geoff Lang1c0ad622015-03-24 10:27:45 -0400344 if (mFunctions->texStorage3D)
345 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400346 mFunctions->texStorage3D(target, levels, texStorageFormat.internalFormat, size.width,
347 size.height, size.depth);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400348 }
349 else
350 {
351 // Make sure no pixel unpack buffer is bound
352 mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
353
354 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
355
356 // Internal format must be sized
357 ASSERT(internalFormatInfo.pixelBytes != 0);
358
359 for (size_t i = 0; i < levels; i++)
360 {
361 gl::Extents levelSize(std::max(size.width >> i, 1),
362 std::max(size.height >> i, 1),
363 mTextureType == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth);
364
Geoff Lang42c98f62015-05-20 14:09:25 -0400365 if (internalFormatInfo.compressed)
366 {
367 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height) * levelSize.depth;
Geoff Lang23a2ae02015-07-28 12:42:52 -0400368 mFunctions->compressedTexImage3D(target, i, texStorageFormat.internalFormat,
369 levelSize.width, levelSize.height,
370 levelSize.depth, 0, dataSize, nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400371 }
372 else
373 {
Geoff Lang23a2ae02015-07-28 12:42:52 -0400374 mFunctions->texImage3D(target, i, texStorageFormat.internalFormat,
375 levelSize.width, levelSize.height, levelSize.depth, 0,
376 internalFormatInfo.format, internalFormatInfo.type,
377 nullptr);
Geoff Lang42c98f62015-05-20 14:09:25 -0400378 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400379 }
380 }
Geoff Langc05f7062015-03-10 09:50:57 -0700381 }
382 else
383 {
384 UNREACHABLE();
385 }
386
387 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500388}
389
Gregoire Payen de La Garanderie752ce192015-04-14 11:11:12 +0100390gl::Error TextureGL::generateMipmaps(const gl::SamplerState &samplerState)
Geoff Langf9a6f082015-01-22 13:32:49 -0500391{
Geoff Langc05f7062015-03-10 09:50:57 -0700392 mStateManager->bindTexture(mTextureType, mTextureID);
393 mFunctions->generateMipmap(mTextureType);
394 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500395}
396
397void TextureGL::bindTexImage(egl::Surface *surface)
398{
Geoff Lang03053202015-04-09 11:21:13 -0400399 ASSERT(mTextureType == GL_TEXTURE_2D);
400
401 // Make sure this texture is bound
402 mStateManager->bindTexture(mTextureType, mTextureID);
Geoff Langf9a6f082015-01-22 13:32:49 -0500403}
404
405void TextureGL::releaseTexImage()
406{
Geoff Lang03053202015-04-09 11:21:13 -0400407 // Not all Surface implementations reset the size of mip 0 when releasing, do it manually
408 ASSERT(mTextureType == GL_TEXTURE_2D);
409
410 mStateManager->bindTexture(mTextureType, mTextureID);
411 if (UseTexImage2D(mTextureType))
412 {
413 mFunctions->texImage2D(mTextureType, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
414 }
415 else
416 {
417 UNREACHABLE();
418 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500419}
420
Geoff Langc05f7062015-03-10 09:50:57 -0700421template <typename T>
422static inline void SyncSamplerStateMember(const FunctionsGL *functions, const gl::SamplerState &newState,
423 gl::SamplerState &curState, GLenum textureType, GLenum name,
424 T(gl::SamplerState::*samplerMember))
425{
426 if (curState.*samplerMember != newState.*samplerMember)
427 {
428 curState.*samplerMember = newState.*samplerMember;
Minmin Gong794e0002015-04-07 18:31:54 -0700429 functions->texParameterf(textureType, name, static_cast<GLfloat>(curState.*samplerMember));
Geoff Langc05f7062015-03-10 09:50:57 -0700430 }
431}
432
433void TextureGL::syncSamplerState(const gl::SamplerState &samplerState) const
434{
435 if (mAppliedSamplerState != samplerState)
436 {
437 mStateManager->bindTexture(mTextureType, mTextureID);
438 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter);
439 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter);
440 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS);
441 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT);
442 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR);
443 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy);
444 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_BASE_LEVEL, &gl::SamplerState::baseLevel);
445 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LEVEL, &gl::SamplerState::maxLevel);
446 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod);
447 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod);
448 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode);
449 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc);
450 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_R, &gl::SamplerState::swizzleRed);
451 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_G, &gl::SamplerState::swizzleGreen);
452 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_B, &gl::SamplerState::swizzleBlue);
453 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_A, &gl::SamplerState::swizzleAlpha);
454 }
455}
456
457GLuint TextureGL::getTextureID() const
458{
459 return mTextureID;
460}
461
Geoff Langf9a6f082015-01-22 13:32:49 -0500462}