Commit 6ee394a1 by Olli Etuaho Committed by Commit Bot

Add initializer function to more texture formats

All GL RGB formats that ANGLE stores as RGBA formats under the covers need to have their alpha channel set to 1. See GLES 3.0.4 table 3.24 for the relevant spec. In some cases, this is handled by the dataInitializerFunction associated with the format. Previously, some texture formats had the function set correctly, but not all. Associating formats with the datainitializerFormat is now a responsibility of the gen_texture_format_table.py script. The new automation there makes sure that all GL RGB formats emulated with RGBA formats get a data initializer function. Tests are added in end2end_tests for most of the RGB formats. BUG=angleproject:1318 TEST=angle_end2end_tests Change-Id: Iad860357f33d87c625445ea6c58a53af47e0b547 Reviewed-on: https://chromium-review.googlesource.com/328253Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 7a533f74
......@@ -9,6 +9,7 @@
import json
import pprint
import re
template = """// GENERATED FILE - DO NOT EDIT.
// Generated by gen_texture_format_table.py using data from texture_format_data.json
......@@ -24,7 +25,6 @@ template = """// GENERATED FILE - DO NOT EDIT.
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h"
#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/swizzle_format_info.h"
......@@ -118,13 +118,15 @@ const TextureFormat GetD3D11FormatInfo(GLenum internalFormat,
DXGI_FORMAT texFormat,
DXGI_FORMAT srvFormat,
DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat)
DXGI_FORMAT dsvFormat,
InitializeTextureDataFunction internalFormatInitializer)
{{
TextureFormat info;
info.texFormat = texFormat;
info.srvFormat = srvFormat;
info.rtvFormat = rtvFormat;
info.dsvFormat = dsvFormat;
info.dataInitializerFunction = internalFormatInitializer;
// Given a GL internal format, the renderFormat is the DSV format if it is depth- or
// stencil-renderable,
......@@ -196,8 +198,6 @@ const TextureFormat GetD3D11FormatInfo(GLenum internalFormat,
info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN;
}}
// Check if there is an initialization function for this texture format
info.dataInitializerFunction = GetInternalFormatInitializer(internalFormat, texFormat);
// Gather all the load functions for this internal format
info.loadFunctions = GetLoadFunctionsMap(internalFormat, texFormat);
......@@ -243,7 +243,78 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalFormat,
}} // namespace rx
"""
def get_texture_format_item(idx, requirements_fn, angle_format):
# TODO(oetuaho): Expand this code so that it could generate the gl format info tables as well.
def gl_format_channels(internal_format):
if internal_format == 'GL_BGR5_A1_ANGLEX':
return 'bgra'
if internal_format == 'GL_R11F_G11F_B10F':
return 'rgb'
if internal_format == 'GL_RGB5_A1':
return 'rgba'
if internal_format.find('GL_RGB10_A2') == 0:
return 'rgba'
channels_pattern = re.compile('GL_(COMPRESSED_)?(SIGNED_)?(ETC\d_)?([A-Z]+)')
match = re.search(channels_pattern, internal_format)
channels_string = match.group(4)
if channels_string == 'ALPHA':
return 'a'
if channels_string == 'LUMINANCE':
if (internal_format.find('ALPHA') >= 0):
return 'la'
return 'l'
if channels_string == 'SRGB':
if (internal_format.find('ALPHA') >= 0):
return 'rgba'
return 'rgb'
if channels_string == 'DEPTH':
if (internal_format.find('STENCIL') >= 0):
return 'ds'
return 'd'
if channels_string == 'STENCIL':
return 's'
return channels_string.lower()
def get_internal_format_initializer(internal_format, angle_format):
internal_format_initializer = 'nullptr'
gl_channels = gl_format_channels(internal_format)
gl_format_no_alpha = gl_channels == 'rgb' or gl_channels == 'l'
if gl_format_no_alpha and angle_format['channels'] == 'rgba':
if angle_format['texFormat'] == 'DXGI_FORMAT_BC1_UNORM':
# BC1 is a special case since the texture data determines whether each block has an alpha channel or not.
# This if statement is hit by COMPRESSED_RGB_S3TC_DXT1, which is a bit of a mess.
# TODO(oetuaho): Look into whether COMPRESSED_RGB_S3TC_DXT1 works right in general.
# Reference: https://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
pass
elif 'componentType' not in angle_format:
raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format)
elif angle_format['componentType'] == 'byte_uint':
internal_format_initializer = 'Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>'
elif angle_format['componentType'] == 'byte_unorm':
internal_format_initializer = 'Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>'
elif angle_format['componentType'] == 'byte_int':
internal_format_initializer = 'Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>'
elif angle_format['componentType'] == 'byte_snorm':
internal_format_initializer = 'Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>'
elif angle_format['componentType'] == 'half':
internal_format_initializer = 'Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>'
elif angle_format['componentType'] == 'short_uint':
internal_format_initializer = 'Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>'
elif angle_format['componentType'] == 'short_int':
internal_format_initializer = 'Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>'
elif angle_format['componentType'] == 'float':
internal_format_initializer = 'Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>'
elif angle_format['componentType'] == 'int':
internal_format_initializer = 'Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>'
elif angle_format['componentType'] == 'uint':
internal_format_initializer = 'Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>'
else:
raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format)
return internal_format_initializer
def get_texture_format_item(idx, internal_format, requirements_fn, angle_format):
table_data = '';
tex_format = angle_format["texFormat"] if "texFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
......@@ -251,6 +322,8 @@ def get_texture_format_item(idx, requirements_fn, angle_format):
rtv_format = angle_format["rtvFormat"] if "rtvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
dsv_format = angle_format["dsvFormat"] if "dsvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN"
internal_format_initializer = get_internal_format_initializer(internal_format, angle_format)
indent = ' '
if requirements_fn != None:
if idx == 0:
......@@ -264,7 +337,8 @@ def get_texture_format_item(idx, requirements_fn, angle_format):
table_data += indent + ' ' + tex_format + ',\n'
table_data += indent + ' ' + srv_format + ',\n'
table_data += indent + ' ' + rtv_format + ',\n'
table_data += indent + ' ' + dsv_format + ');\n'
table_data += indent + ' ' + dsv_format + ',\n'
table_data += indent + ' ' + internal_format_initializer + ');\n'
table_data += indent + 'return textureFormat;\n'
if requirements_fn != None:
......@@ -282,10 +356,10 @@ def parse_json_into_switch_string(json_map, json_data):
table_data += ' {\n'
if isinstance(json_map[internal_format], basestring):
table_data += get_texture_format_item(0, None, json_data[json_map[internal_format]])
table_data += get_texture_format_item(0, internal_format, None, json_data[json_map[internal_format]])
else:
for idx, requirements_map in enumerate(sorted(json_map[internal_format].iteritems())):
table_data += get_texture_format_item(idx, requirements_map[0], json_data[requirements_map[1]])
table_data += get_texture_format_item(idx, internal_format, requirements_map[0], json_data[requirements_map[1]])
table_data += ' else\n'
table_data += ' {\n'
table_data += ' break;\n'
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// internal_format_initializer_table:
// Contains table to go from internal format and dxgi format to initializer function
// for TextureFormat
//
#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h"
#include "libANGLE/renderer/d3d/loadimage.h"
namespace rx
{
namespace d3d11
{
// TODO: This should be generated by a JSON file
InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat,
DXGI_FORMAT dxgiFormat)
{
switch (internalFormat)
{
case GL_RGB8:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
}
default:
break;
}
}
case GL_RGB565:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
}
default:
break;
}
}
case GL_SRGB8:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
{
return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>;
}
default:
break;
}
}
case GL_RGB16F:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R16G16B16A16_FLOAT:
{
return Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>;
}
default:
break;
}
}
case GL_RGB32F:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R32G32B32A32_FLOAT:
{
return Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000,
gl::Float32One>;
}
default:
break;
}
}
case GL_RGB8UI:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R8G8B8A8_UINT:
{
return Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>;
}
default:
break;
}
}
case GL_RGB8I:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R8G8B8A8_SINT:
{
return Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>;
}
default:
break;
}
}
case GL_RGB16UI:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R16G16B16A16_UINT:
{
return Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>;
}
default:
break;
}
}
case GL_RGB16I:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R16G16B16A16_SINT:
{
return Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>;
}
default:
break;
}
}
case GL_RGB32UI:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R32G32B32A32_UINT:
{
return Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000,
0x00000001>;
}
default:
break;
}
}
case GL_RGB32I:
{
switch (dxgiFormat)
{
case DXGI_FORMAT_R32G32B32A32_SINT:
{
return Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000,
0x00000001>;
}
default:
break;
}
}
default:
{
return nullptr;
}
}
}
} // namespace d3d11
} // namespace rx
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// internal_format_initializer_table:
// Contains table to go from internal format and dxgi format to initializer function
// for TextureFormat
//
#ifndef LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
#define LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include <map>
namespace rx
{
namespace d3d11
{
InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat,
DXGI_FORMAT dxgiFormat);
} // namespace d3d11
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_
......@@ -307,8 +307,6 @@
'libANGLE/renderer/d3d/d3d11/IndexBuffer11.h',
'libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp',
'libANGLE/renderer/d3d/d3d11/InputLayoutCache.h',
'libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h',
'libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp',
'libANGLE/renderer/d3d/d3d11/load_functions_table.h',
'libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp',
'libANGLE/renderer/d3d/d3d11/NativeWindow.h',
......
......@@ -67,6 +67,8 @@ GLColor ReadColor(GLint x, GLint y);
#define EXPECT_PIXEL_EQ(x, y, r, g, b, a) \
EXPECT_EQ(angle::MakeGLColor(r, g, b, a), angle::ReadColor(x, y))
#define EXPECT_PIXEL_ALPHA_EQ(x, y, a) EXPECT_EQ(a, angle::ReadColor(x, y).A)
#define EXPECT_PIXEL_COLOR_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor(x, y))
// TODO(jmadill): Figure out how we can use GLColor's nice printing with EXPECT_NEAR.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment