1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <GLES2/gl2.h>
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <GLES2/gl2ext.h>
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <GLES2/gl2extchromium.h>
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/basictypes.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_manager.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_test_utils.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#define SHADER(src) #src
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace gpu {
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kRedMask = 0xF800;
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kGreenMask = 0x07E0;
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kBlueMask = 0x001F;
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Color palette in 565 format.
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kPalette[] = {
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kGreenMask | kBlueMask,   // Cyan.
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kBlueMask  | kRedMask,    // Magenta.
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kRedMask   | kGreenMask,  // Yellow.
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  0x0000,                   // Black.
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kRedMask,                 // Red.
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kGreenMask,               // Green.
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kBlueMask,                // Blue.
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  0xFFFF,                   // White.
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const unsigned kBlockSize = 4;
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const unsigned kPaletteSize = sizeof(kPalette) / sizeof(kPalette[0]);
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const unsigned kTextureWidth = kBlockSize * kPaletteSize;
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const unsigned kTextureHeight = kBlockSize;
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const char* extension(GLenum format) {
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch(format) {
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return "GL_EXT_texture_compression_dxt1";
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return "GL_CHROMIUM_texture_compression_dxt3";
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return "GL_CHROMIUM_texture_compression_dxt5";
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      NOTREACHED();
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Index that chooses the given colors (color_0 and color_1),
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// not the interpolated colors (color_2 and color_3).
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kColor0 = 0x0000;
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const uint16 kColor1 = 0x5555;
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static GLuint LoadCompressedTexture(const void* data,
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    GLsizeiptr size,
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    GLenum format,
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    GLsizei width,
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    GLsizei height) {
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint texture;
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glGenTextures(1, &texture);
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, texture);
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glCompressedTexImage2D(
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GL_TEXTURE_2D, 0, format, width, height, 0, size, data);
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return texture;
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)GLuint LoadTextureDXT1(bool alpha) {
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const unsigned kStride = 4;
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint16 data[kStride * kPaletteSize];
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (unsigned i = 0; i < kPaletteSize; ++i) {
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Each iteration defines a 4x4 block of texture.
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    unsigned j = kStride * i;
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_0.
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_1.
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor0;  // color index.
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor1;  // color index.
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLenum format = alpha ?
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return LoadCompressedTexture(
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      data, sizeof(data), format, kTextureWidth, kTextureHeight);
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)GLuint LoadTextureDXT3() {
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const unsigned kStride = 8;
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const uint16 kOpaque = 0xFFFF;
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint16 data[kStride * kPaletteSize];
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (unsigned i = 0; i < kPaletteSize; ++i) {
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Each iteration defines a 4x4 block of texture.
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    unsigned j = kStride * i;
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kOpaque;  // alpha row 0.
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kOpaque;  // alpha row 1.
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kOpaque;  // alpha row 2.
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kOpaque;  // alpha row 3.
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_0.
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_1.
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor0;  // color index.
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor1;  // color index.
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return LoadCompressedTexture(data,
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               sizeof(data),
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               kTextureWidth,
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               kTextureHeight);
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)GLuint LoadTextureDXT5() {
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const unsigned kStride = 8;
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const uint16 kClear = 0x0000;
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const uint16 kAlpha7 = 0xFFFF;  // Opaque alpha index.
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint16 data[kStride * kPaletteSize];
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (unsigned i = 0; i < kPaletteSize; ++i) {
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Each iteration defines a 4x4 block of texture.
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    unsigned j = kStride * i;
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kClear;  // alpha_0 | alpha_1.
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kAlpha7;  // alpha index.
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kAlpha7;  // alpha index.
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kAlpha7;  // alpha index.
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_0.
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kPalette[i];  // color_1.
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor0;  // color index.
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    data[j++] = kColor1;  // color index.
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return LoadCompressedTexture(data,
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               sizeof(data),
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               kTextureWidth,
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               kTextureHeight);
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static void ToRGB888(uint16 rgb565, uint8 rgb888[]) {
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint8 r5 = (rgb565 & kRedMask)   >> 11;
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint8 g6 = (rgb565 & kGreenMask) >> 5;
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint8 b5 = (rgb565 & kBlueMask);
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Replicate upper bits to lower empty bits.
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  rgb888[0] = (r5 << 3) | (r5 >> 2);
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  rgb888[1] = (g6 << 2) | (g6 >> 4);
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  rgb888[2] = (b5 << 3) | (b5 >> 2);
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CompressedTextureTest : public ::testing::TestWithParam<GLenum> {
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) protected:
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void SetUp() {
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    GLManager::Options options;
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    options.size = gfx::Size(kTextureWidth, kTextureHeight);
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gl_.Initialize(options);
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void TearDown() {
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gl_.Destroy();
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint LoadProgram() {
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const char* v_shader_src = SHADER(
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        attribute vec2 a_position;
164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        varying vec2 v_texcoord;
165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        void main() {
166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          gl_Position = vec4(a_position, 0.0, 1.0);
167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          v_texcoord = (a_position + 1.0) * 0.5;
168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        }
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    );
170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const char* f_shader_src = SHADER(
171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        precision mediump float;
172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        uniform sampler2D u_texture;
173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        varying vec2 v_texcoord;
174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        void main() {
175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          gl_FragColor = texture2D(u_texture, v_texcoord);
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        }
177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    );
178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return GLTestHelper::LoadProgram(v_shader_src, f_shader_src);
179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint LoadTexture(GLenum format) {
182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    switch (format) {
183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return LoadTextureDXT1(false);
184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return LoadTextureDXT1(true);
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return LoadTextureDXT3();
186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return LoadTextureDXT5();
187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      default: NOTREACHED();
188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return 0;
190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLManager gl_;
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// The test draws a texture in the given format and verifies that the drawn
197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// pixels are of the same color as the texture.
198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// The texture consists of 4x4 blocks of texels (same as DXT), one for each
199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// color defined in kPalette.
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_P(CompressedTextureTest, Draw) {
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLenum format = GetParam();
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // This test is only valid if compressed texture extension is supported.
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const char* ext = extension(format);
205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!GLTestHelper::HasExtension(ext))
206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Load shader program.
209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint program = LoadProgram();
210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NE(program, 0u);
211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLint position_loc = glGetAttribLocation(program, "a_position");
212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLint texture_loc = glGetUniformLocation(program, "u_texture");
213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NE(position_loc, -1);
214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NE(texture_loc, -1);
215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glUseProgram(program);
216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Load geometry.
218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NE(vbo, 0u);
220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Load texture.
222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint texture = LoadTexture(format);
223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_NE(texture, 0u);
224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glActiveTexture(GL_TEXTURE0);
225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, texture);
226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glUniform1i(texture_loc, 0);
227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Draw.
229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glDrawArrays(GL_TRIANGLES, 0, 6);
230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glFlush();
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify results.
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int origin[] = {0, 0};
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint8 expected_rgba[] = {0, 0, 0, 255};
235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (unsigned i = 0; i < kPaletteSize; ++i) {
236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    origin[0] = kBlockSize * i;
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ToRGB888(kPalette[i], expected_rgba);
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(GLTestHelper::CheckPixels(origin[0], origin[1],
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                          kBlockSize, kBlockSize,
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                          0, expected_rgba));
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLTestHelper::CheckGLError("CompressedTextureTest.Draw", __LINE__);
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const GLenum kFormats[] = {
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(Format,
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        CompressedTextureTest,
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        ::testing::ValuesIn(kFormats));
254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace gpu
256