blob: acd4cf12388df79ac921bb5786740ef9374f2c11 [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 -040059static const nativegl::InternalFormat &GetNativeInternalFormat(const FunctionsGL *functions,
60 const WorkaroundsGL &workarounds,
61 GLenum internalFormat,
62 GLenum type)
63{
64 GLenum sizedFormat = gl::GetSizedInternalFormat(internalFormat, type);
65 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
66
67 bool use1BitAlphaWorkaround = workarounds.avoid1BitAlphaTextureFormats &&
68 functions->standard == STANDARD_GL_DESKTOP &&
69 formatInfo.alphaBits == 1;
70 if (!use1BitAlphaWorkaround &&
71 (functions->standard == STANDARD_GL_DESKTOP || functions->isAtLeastGLES(gl::Version(3, 0))))
72 {
73 // Use sized internal formats whenever possible to guarantee the requested precision.
74 // On Desktop GL, passing an internal format of GL_RGBA will generate a GL_RGBA8 texture
75 // even if the provided type is GL_FLOAT.
76 return nativegl::GetInternalFormatInfo(sizedFormat, functions->standard);
77 }
78 else
79 {
80 // Use the original unsized format when the workaround is required or on top of ES2.
81 return nativegl::GetInternalFormatInfo(formatInfo.format, functions->standard);
82 }
83}
84
85TextureGL::TextureGL(GLenum type,
86 const FunctionsGL *functions,
87 const WorkaroundsGL &workarounds,
88 StateManagerGL *stateManager)
Geoff Langc05f7062015-03-10 09:50:57 -070089 : TextureImpl(),
90 mTextureType(type),
91 mFunctions(functions),
Geoff Lang14389cc2015-07-23 10:57:20 -040092 mWorkarounds(workarounds),
Geoff Langc05f7062015-03-10 09:50:57 -070093 mStateManager(stateManager),
94 mAppliedSamplerState(),
95 mTextureID(0)
96{
97 ASSERT(mFunctions);
98 ASSERT(mStateManager);
99
100 mFunctions->genTextures(1, &mTextureID);
Geoff Lang90d98af2015-05-26 16:41:38 -0400101 mStateManager->bindTexture(mTextureType, mTextureID);
Geoff Langc05f7062015-03-10 09:50:57 -0700102}
Geoff Langf9a6f082015-01-22 13:32:49 -0500103
104TextureGL::~TextureGL()
Geoff Langc05f7062015-03-10 09:50:57 -0700105{
Geoff Lang1eb708e2015-05-04 14:58:23 -0400106 mStateManager->deleteTexture(mTextureID);
107 mTextureID = 0;
Geoff Langc05f7062015-03-10 09:50:57 -0700108}
Geoff Langf9a6f082015-01-22 13:32:49 -0500109
110void TextureGL::setUsage(GLenum usage)
111{
Geoff Langc05f7062015-03-10 09:50:57 -0700112 // GL_ANGLE_texture_usage not implemented for desktop GL
113 UNREACHABLE();
Geoff Langf9a6f082015-01-22 13:32:49 -0500114}
115
116gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
117 const gl::PixelUnpackState &unpack, const uint8_t *pixels)
118{
Geoff Langfb2a5592015-03-20 11:25:37 -0400119 UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings.
Geoff Lang968992e2015-03-17 18:01:49 -0400120 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700121
122 SetUnpackStateForTexImage(mStateManager, unpack);
123
Geoff Lang14389cc2015-07-23 10:57:20 -0400124 const nativegl::InternalFormat &nativeInternalFormatInfo =
125 GetNativeInternalFormat(mFunctions, mWorkarounds, internalFormat, type);
Geoff Langfd216c42015-05-27 16:12:30 -0400126
Geoff Langc05f7062015-03-10 09:50:57 -0700127 mStateManager->bindTexture(mTextureType, mTextureID);
128 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400129 {
Geoff Langc05f7062015-03-10 09:50:57 -0700130 ASSERT(size.depth == 1);
Geoff Langfd216c42015-05-27 16:12:30 -0400131 mFunctions->texImage2D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, 0, format, type, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700132 }
133 else if (UseTexImage3D(mTextureType))
134 {
Geoff Langfd216c42015-05-27 16:12:30 -0400135 mFunctions->texImage3D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth, 0, format, type, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700136 }
137 else
138 {
139 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400140 }
141
Geoff Langc05f7062015-03-10 09:50:57 -0700142 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500143}
144
145gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
146 const gl::PixelUnpackState &unpack, const uint8_t *pixels)
147{
Geoff Lang968992e2015-03-17 18:01:49 -0400148 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700149
150 SetUnpackStateForTexImage(mStateManager, unpack);
151
152 mStateManager->bindTexture(mTextureType, mTextureID);
153 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400154 {
Geoff Langc05f7062015-03-10 09:50:57 -0700155 ASSERT(area.z == 0 && area.depth == 1);
156 mFunctions->texSubImage2D(target, level, area.x, area.y, area.width, area.height, format, type, pixels);
157 }
158 else if (UseTexImage3D(mTextureType))
159 {
160 mFunctions->texSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth,
161 format, type, pixels);
162 }
163 else
164 {
165 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400166 }
167
Geoff Langc05f7062015-03-10 09:50:57 -0700168 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500169}
170
171gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
Geoff Lang8509d862015-05-20 14:06:13 -0400172 const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
Geoff Langf9a6f082015-01-22 13:32:49 -0500173{
Geoff Lang968992e2015-03-17 18:01:49 -0400174 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700175
176 SetUnpackStateForTexImage(mStateManager, unpack);
177
Geoff Lang14389cc2015-07-23 10:57:20 -0400178 const nativegl::InternalFormat &nativeInternalFormatInfo =
179 GetNativeInternalFormat(mFunctions, mWorkarounds, internalFormat, GL_UNSIGNED_BYTE);
Geoff Langfd216c42015-05-27 16:12:30 -0400180
Geoff Langc05f7062015-03-10 09:50:57 -0700181 mStateManager->bindTexture(mTextureType, mTextureID);
182 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400183 {
Geoff Langc05f7062015-03-10 09:50:57 -0700184 ASSERT(size.depth == 1);
Geoff Langfd216c42015-05-27 16:12:30 -0400185 mFunctions->compressedTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, 0, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700186 }
187 else if (UseTexImage3D(mTextureType))
188 {
Geoff Langfd216c42015-05-27 16:12:30 -0400189 mFunctions->compressedTexImage3D(target, level, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth, 0,
Geoff Lang8509d862015-05-20 14:06:13 -0400190 imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700191 }
192 else
193 {
194 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400195 }
196
Geoff Langc05f7062015-03-10 09:50:57 -0700197 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500198}
199
200gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
Geoff Lang8509d862015-05-20 14:06:13 -0400201 const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
Geoff Langf9a6f082015-01-22 13:32:49 -0500202{
Geoff Lang968992e2015-03-17 18:01:49 -0400203 ASSERT(CompatibleTextureTarget(mTextureType, target));
Geoff Langc05f7062015-03-10 09:50:57 -0700204
205 SetUnpackStateForTexImage(mStateManager, unpack);
206
Geoff Langc05f7062015-03-10 09:50:57 -0700207 mStateManager->bindTexture(mTextureType, mTextureID);
208 if (UseTexImage2D(mTextureType))
Jamie Madill67102f02015-03-16 10:41:42 -0400209 {
Geoff Langc05f7062015-03-10 09:50:57 -0700210 ASSERT(area.z == 0 && area.depth == 1);
Geoff Lang14389cc2015-07-23 10:57:20 -0400211 mFunctions->compressedTexSubImage2D(target, level, area.x, area.y, area.width, area.height,
212 format, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700213 }
214 else if (UseTexImage3D(mTextureType))
215 {
Geoff Lang14389cc2015-07-23 10:57:20 -0400216 mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width,
217 area.height, area.depth, format, imageSize, pixels);
Geoff Langc05f7062015-03-10 09:50:57 -0700218 }
219 else
220 {
221 UNREACHABLE();
Jamie Madill67102f02015-03-16 10:41:42 -0400222 }
223
Geoff Langc05f7062015-03-10 09:50:57 -0700224 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500225}
226
227gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
228 const gl::Framebuffer *source)
229{
Geoff Lang14389cc2015-07-23 10:57:20 -0400230 const nativegl::InternalFormat &nativeInternalFormatInfo = GetNativeInternalFormat(
231 mFunctions, mWorkarounds, internalFormat, source->getImplementationColorReadType());
Geoff Langfd216c42015-05-27 16:12:30 -0400232
Geoff Langfbfa47c2015-03-31 11:26:00 -0400233 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
234
235 mStateManager->bindTexture(mTextureType, mTextureID);
236 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
237
238 if (UseTexImage2D(mTextureType))
239 {
Geoff Langfd216c42015-05-27 16:12:30 -0400240 mFunctions->copyTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, sourceArea.x, sourceArea.y,
Geoff Langfbfa47c2015-03-31 11:26:00 -0400241 sourceArea.width, sourceArea.height, 0);
242 }
243 else
244 {
245 UNREACHABLE();
246 }
247
248 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500249}
250
251gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
252 const gl::Framebuffer *source)
253{
Geoff Langfbfa47c2015-03-31 11:26:00 -0400254 const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
255
256 mStateManager->bindTexture(mTextureType, mTextureID);
257 mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
258
259 if (UseTexImage2D(mTextureType))
260 {
261 ASSERT(destOffset.z == 0);
262 mFunctions->copyTexSubImage2D(target, level, destOffset.x, destOffset.y,
263 sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
264 }
265 else if (UseTexImage3D(mTextureType))
266 {
267 mFunctions->copyTexSubImage3D(target, level, destOffset.x, destOffset.y, destOffset.z,
268 sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
269 }
270 else
271 {
272 UNREACHABLE();
273 }
274
275 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500276}
277
278gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
279{
Geoff Langc05f7062015-03-10 09:50:57 -0700280 // TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the
281 // ARB_texture_storage extension is not available.
282
Geoff Langfd216c42015-05-27 16:12:30 -0400283 const nativegl::InternalFormat &nativeInternalFormatInfo = nativegl::GetInternalFormatInfo(internalFormat, mFunctions->standard);
284
Geoff Langc05f7062015-03-10 09:50:57 -0700285 mStateManager->bindTexture(mTextureType, mTextureID);
286 if (UseTexImage2D(mTextureType))
287 {
288 ASSERT(size.depth == 1);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400289 if (mFunctions->texStorage2D)
290 {
Geoff Langfd216c42015-05-27 16:12:30 -0400291 mFunctions->texStorage2D(target, levels, nativeInternalFormatInfo.internalFormat, size.width, size.height);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400292 }
293 else
294 {
295 // Make sure no pixel unpack buffer is bound
296 mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
297
298 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
299
300 // Internal format must be sized
301 ASSERT(internalFormatInfo.pixelBytes != 0);
302
303 for (size_t level = 0; level < levels; level++)
304 {
305 gl::Extents levelSize(std::max(size.width >> level, 1),
306 std::max(size.height >> level, 1),
307 1);
308
309 if (mTextureType == GL_TEXTURE_2D)
310 {
Geoff Lang42c98f62015-05-20 14:09:25 -0400311 if (internalFormatInfo.compressed)
312 {
313 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
Geoff Langfd216c42015-05-27 16:12:30 -0400314 mFunctions->compressedTexImage2D(target, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
Geoff Lang42c98f62015-05-20 14:09:25 -0400315 0, dataSize, nullptr);
316 }
317 else
318 {
Geoff Langfd216c42015-05-27 16:12:30 -0400319 mFunctions->texImage2D(target, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
Geoff Lang42c98f62015-05-20 14:09:25 -0400320 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
321 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400322 }
323 else if (mTextureType == GL_TEXTURE_CUBE_MAP)
324 {
325 for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++)
326 {
Geoff Lang42c98f62015-05-20 14:09:25 -0400327 if (internalFormatInfo.compressed)
328 {
329 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height);
Geoff Langfd216c42015-05-27 16:12:30 -0400330 mFunctions->compressedTexImage2D(face, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
Geoff Lang42c98f62015-05-20 14:09:25 -0400331 0, dataSize, nullptr);
332 }
333 else
334 {
Geoff Langfd216c42015-05-27 16:12:30 -0400335 mFunctions->texImage2D(face, level, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height,
Geoff Lang42c98f62015-05-20 14:09:25 -0400336 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
337 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400338 }
339 }
340 else
341 {
342 UNREACHABLE();
343 }
344 }
345 }
Geoff Langc05f7062015-03-10 09:50:57 -0700346 }
347 else if (UseTexImage3D(mTextureType))
348 {
Geoff Lang1c0ad622015-03-24 10:27:45 -0400349 if (mFunctions->texStorage3D)
350 {
Geoff Langfd216c42015-05-27 16:12:30 -0400351 mFunctions->texStorage3D(target, levels, nativeInternalFormatInfo.internalFormat, size.width, size.height, size.depth);
Geoff Lang1c0ad622015-03-24 10:27:45 -0400352 }
353 else
354 {
355 // Make sure no pixel unpack buffer is bound
356 mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
357
358 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
359
360 // Internal format must be sized
361 ASSERT(internalFormatInfo.pixelBytes != 0);
362
363 for (size_t i = 0; i < levels; i++)
364 {
365 gl::Extents levelSize(std::max(size.width >> i, 1),
366 std::max(size.height >> i, 1),
367 mTextureType == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth);
368
Geoff Lang42c98f62015-05-20 14:09:25 -0400369 if (internalFormatInfo.compressed)
370 {
371 size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height) * levelSize.depth;
Geoff Langfd216c42015-05-27 16:12:30 -0400372 mFunctions->compressedTexImage3D(target, i, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height, levelSize.depth,
Geoff Lang42c98f62015-05-20 14:09:25 -0400373 0, dataSize, nullptr);
374 }
375 else
376 {
Geoff Langfd216c42015-05-27 16:12:30 -0400377 mFunctions->texImage3D(target, i, nativeInternalFormatInfo.internalFormat, levelSize.width, levelSize.height, levelSize.depth,
Geoff Lang42c98f62015-05-20 14:09:25 -0400378 0, internalFormatInfo.format, internalFormatInfo.type, nullptr);
379 }
Geoff Lang1c0ad622015-03-24 10:27:45 -0400380 }
381 }
Geoff Langc05f7062015-03-10 09:50:57 -0700382 }
383 else
384 {
385 UNREACHABLE();
386 }
387
388 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500389}
390
Gregoire Payen de La Garanderie752ce192015-04-14 11:11:12 +0100391gl::Error TextureGL::generateMipmaps(const gl::SamplerState &samplerState)
Geoff Langf9a6f082015-01-22 13:32:49 -0500392{
Geoff Langc05f7062015-03-10 09:50:57 -0700393 mStateManager->bindTexture(mTextureType, mTextureID);
394 mFunctions->generateMipmap(mTextureType);
395 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500396}
397
398void TextureGL::bindTexImage(egl::Surface *surface)
399{
Geoff Lang03053202015-04-09 11:21:13 -0400400 ASSERT(mTextureType == GL_TEXTURE_2D);
401
402 // Make sure this texture is bound
403 mStateManager->bindTexture(mTextureType, mTextureID);
Geoff Langf9a6f082015-01-22 13:32:49 -0500404}
405
406void TextureGL::releaseTexImage()
407{
Geoff Lang03053202015-04-09 11:21:13 -0400408 // Not all Surface implementations reset the size of mip 0 when releasing, do it manually
409 ASSERT(mTextureType == GL_TEXTURE_2D);
410
411 mStateManager->bindTexture(mTextureType, mTextureID);
412 if (UseTexImage2D(mTextureType))
413 {
414 mFunctions->texImage2D(mTextureType, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
415 }
416 else
417 {
418 UNREACHABLE();
419 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500420}
421
Geoff Langc05f7062015-03-10 09:50:57 -0700422template <typename T>
423static inline void SyncSamplerStateMember(const FunctionsGL *functions, const gl::SamplerState &newState,
424 gl::SamplerState &curState, GLenum textureType, GLenum name,
425 T(gl::SamplerState::*samplerMember))
426{
427 if (curState.*samplerMember != newState.*samplerMember)
428 {
429 curState.*samplerMember = newState.*samplerMember;
Minmin Gong794e0002015-04-07 18:31:54 -0700430 functions->texParameterf(textureType, name, static_cast<GLfloat>(curState.*samplerMember));
Geoff Langc05f7062015-03-10 09:50:57 -0700431 }
432}
433
434void TextureGL::syncSamplerState(const gl::SamplerState &samplerState) const
435{
436 if (mAppliedSamplerState != samplerState)
437 {
438 mStateManager->bindTexture(mTextureType, mTextureID);
439 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter);
440 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter);
441 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS);
442 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT);
443 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR);
444 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy);
445 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_BASE_LEVEL, &gl::SamplerState::baseLevel);
446 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LEVEL, &gl::SamplerState::maxLevel);
447 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod);
448 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod);
449 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode);
450 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc);
451 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_R, &gl::SamplerState::swizzleRed);
452 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_G, &gl::SamplerState::swizzleGreen);
453 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_B, &gl::SamplerState::swizzleBlue);
454 SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_A, &gl::SamplerState::swizzleAlpha);
455 }
456}
457
458GLuint TextureGL::getTextureID() const
459{
460 return mTextureID;
461}
462
Geoff Langf9a6f082015-01-22 13:32:49 -0500463}