Commit d2b50a0b by Jamie Madill Committed by Commit Bot

Move ReadPixels logic to helper methods.

These routines were pretty much duplicated between D3D9 and D3D11. Since I was going to have to rewrite them again for Vulkan, I figured it would be best to move them into a common location and clean them up a bit. BUG=angleproject:1319 Change-Id: I15d39b052daf3e1020dbd0880f01ae84f3686a0a Reviewed-on: https://chromium-review.googlesource.com/349630Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 6e4d1d21
...@@ -20,14 +20,28 @@ namespace gl ...@@ -20,14 +20,28 @@ namespace gl
// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
// format and type combinations. // format and type combinations.
typedef std::pair<GLenum, GLenum> FormatTypePair; typedef std::pair<FormatType, GLenum> FormatPair;
typedef std::pair<FormatTypePair, GLenum> FormatPair; typedef std::map<FormatType, GLenum> FormatMap;
typedef std::map<FormatTypePair, GLenum> FormatMap;
FormatType::FormatType() : format(GL_NONE), type(GL_NONE)
{
}
FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_)
{
}
bool FormatType::operator<(const FormatType &other) const
{
if (format != other.format)
return format < other.format;
return type < other.type;
}
// A helper function to insert data into the format map with fewer characters. // A helper function to insert data into the format map with fewer characters.
static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat) static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
{ {
map->insert(FormatPair(FormatTypePair(format, type), internalFormat)); map->insert(FormatPair(FormatType(format, type), internalFormat));
} }
FormatMap BuildFormatMap() FormatMap BuildFormatMap()
...@@ -799,7 +813,7 @@ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type) ...@@ -799,7 +813,7 @@ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
} }
static const FormatMap formatMap = BuildFormatMap(); static const FormatMap formatMap = BuildFormatMap();
auto iter = formatMap.find(FormatTypePair(internalFormat, type)); auto iter = formatMap.find(FormatType(internalFormat, type));
if (iter != formatMap.end()) if (iter != formatMap.end())
{ {
return iter->second; return iter->second;
......
...@@ -20,6 +20,19 @@ ...@@ -20,6 +20,19 @@
namespace gl namespace gl
{ {
struct FormatType final
{
FormatType();
FormatType(GLenum format_, GLenum type_);
FormatType(const FormatType &other) = default;
FormatType &operator=(const FormatType &other) = default;
bool operator<(const FormatType &other) const;
GLenum format;
GLenum type;
};
struct Type struct Type
{ {
Type(); Type();
......
...@@ -6,17 +6,17 @@ ...@@ -6,17 +6,17 @@
// copyimage.cpp: Defines image copying functions // copyimage.cpp: Defines image copying functions
#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/copyimage.h"
namespace rx namespace rx
{ {
void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest) void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest)
{ {
uint32_t argb = *reinterpret_cast<const uint32_t*>(source); uint32_t argb = *reinterpret_cast<const uint32_t *>(source);
*reinterpret_cast<uint32_t*>(dest) = (argb & 0xFF00FF00) | // Keep alpha and green *reinterpret_cast<uint32_t *>(dest) = (argb & 0xFF00FF00) | // Keep alpha and green
(argb & 0x00FF0000) >> 16 | // Move red to blue (argb & 0x00FF0000) >> 16 | // Move red to blue
(argb & 0x000000FF) << 16; // Move blue to red (argb & 0x000000FF) << 16; // Move blue to red
} }
} } // namespace rx
...@@ -28,8 +28,8 @@ void CopyPixel(const uint8_t *source, uint8_t *dest); ...@@ -28,8 +28,8 @@ void CopyPixel(const uint8_t *source, uint8_t *dest);
void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest); void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest);
} } // namespace rx
#include "copyimage.inl" #include "copyimage.inl"
#endif // LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ #endif // LIBANGLE_RENDERER_D3D_COPYIMAGE_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <memory> #include <memory>
#include "common/MemoryBuffer.h" #include "common/MemoryBuffer.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
...@@ -39,27 +40,6 @@ enum class CopyResult ...@@ -39,27 +40,6 @@ enum class CopyResult
} // anonymous namespace } // anonymous namespace
PackPixelsParams::PackPixelsParams()
: format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0)
{
}
PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
GLenum formatIn,
GLenum typeIn,
GLuint outputPitchIn,
const gl::PixelPackState &packIn,
ptrdiff_t offsetIn)
: area(areaIn),
format(formatIn),
type(typeIn),
outputPitch(outputPitchIn),
packBuffer(packIn.pixelBuffer.get()),
pack(packIn.alignment, packIn.reverseRowOrder),
offset(offsetIn)
{
}
namespace gl_d3d11 namespace gl_d3d11
{ {
......
...@@ -22,6 +22,7 @@ class FramebufferAttachment; ...@@ -22,6 +22,7 @@ class FramebufferAttachment;
namespace rx namespace rx
{ {
struct PackPixelsParams;
class Renderer11; class Renderer11;
struct SourceIndexData; struct SourceIndexData;
struct TranslatedAttribute; struct TranslatedAttribute;
...@@ -40,21 +41,6 @@ enum BufferUsage ...@@ -40,21 +41,6 @@ enum BufferUsage
BUFFER_USAGE_COUNT, BUFFER_USAGE_COUNT,
}; };
struct PackPixelsParams
{
PackPixelsParams();
PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
const gl::PixelPackState &pack, ptrdiff_t offset);
gl::Rectangle area;
GLenum format;
GLenum type;
GLuint outputPitch;
gl::Buffer *packBuffer;
gl::PixelPackState pack;
ptrdiff_t offset;
};
typedef size_t DataRevision; typedef size_t DataRevision;
class Buffer11 : public BufferD3D class Buffer11 : public BufferD3D
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/histogram_macros.h" #include "libANGLE/histogram_macros.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/CompilerD3D.h" #include "libANGLE/renderer/d3d/CompilerD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Blit11.h" #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
...@@ -3756,79 +3757,17 @@ gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, ...@@ -3756,79 +3757,17 @@ gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr); return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr);
} }
uint8_t *source; uint8_t *source = static_cast<uint8_t *>(mapping.pData);
int inputPitch; int inputPitch = static_cast<int>(mapping.RowPitch);
if (params.pack.reverseRowOrder)
{
source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
inputPitch = -static_cast<int>(mapping.RowPitch);
}
else
{
source = static_cast<uint8_t*>(mapping.pData);
inputPitch = static_cast<int>(mapping.RowPitch);
}
const auto &angleFormatInfo = d3d11::GetANGLEFormatSet(textureHelper.getANGLEFormat()); const auto &angleFormatInfo = d3d11::GetANGLEFormatSet(textureHelper.getANGLEFormat());
const gl::InternalFormat &sourceFormatInfo = const gl::InternalFormat &sourceFormatInfo =
gl::GetInternalFormatInfo(angleFormatInfo.glInternalFormat); gl::GetInternalFormatInfo(angleFormatInfo.glInternalFormat);
if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureHelper.getFormat());
{ ColorReadFunction colorReadFunction = angleFormatInfo.colorReadFunction;
uint8_t *dest = pixelsOut + params.offset;
for (int y = 0; y < params.area.height; y++)
{
memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes);
}
}
else
{
const d3d11::DXGIFormat &dxgiFormatInfo =
d3d11::GetDXGIFormatInfo(textureHelper.getFormat());
ColorCopyFunction fastCopyFunc =
dxgiFormatInfo.getFastCopyFunction(params.format, params.type);
GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type);
const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
if (fastCopyFunc)
{
// Fast copy is possible through some special function
for (int y = 0; y < params.area.height; y++)
{
for (int x = 0; x < params.area.width; x++)
{
uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
fastCopyFunc(src, dest); PackPixels(params, sourceFormatInfo, dxgiFormatInfo.fastCopyFunctions, colorReadFunction,
} inputPitch, source, pixelsOut);
}
}
else
{
ColorReadFunction colorReadFunction = angleFormatInfo.colorReadFunction;
ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type);
uint8_t temp[16]; // Maximum size of any Color<T> type used.
static_assert(sizeof(temp) >= sizeof(gl::ColorF) &&
sizeof(temp) >= sizeof(gl::ColorUI) &&
sizeof(temp) >= sizeof(gl::ColorI),
"Unexpected size of gl::Color struct.");
for (int y = 0; y < params.area.height; y++)
{
for (int x = 0; x < params.area.width; x++)
{
uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
colorReadFunction(src, temp);
colorWriteFunction(temp, dest);
}
}
}
}
mDeviceContext->Unmap(readResource, 0); mDeviceContext->Unmap(readResource, 0);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/copyimage.h"
#include "libANGLE/renderer/d3d/d3d11/copyvertex.h" #include "libANGLE/renderer/d3d/d3d11/copyvertex.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
...@@ -39,15 +39,25 @@ struct D3D11FastCopyFormat ...@@ -39,15 +39,25 @@ struct D3D11FastCopyFormat
} }
}; };
typedef std::multimap<DXGI_FORMAT, D3D11FastCopyFormat> D3D11FastCopyMap; static const FastCopyFunctionMap &GetFastCopyFunctionMap(DXGI_FORMAT dxgiFormat)
static D3D11FastCopyMap BuildFastCopyMap()
{ {
D3D11FastCopyMap map; switch (dxgiFormat)
{
map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); case DXGI_FORMAT_B8G8R8A8_UNORM:
{
return map; static FastCopyFunctionMap fastCopyMap;
if (fastCopyMap.empty())
{
fastCopyMap[gl::FormatType(GL_RGBA, GL_UNSIGNED_BYTE)] = CopyBGRA8ToRGBA8;
}
return fastCopyMap;
}
default:
{
static FastCopyFunctionMap emptyMap;
return emptyMap;
}
}
} }
struct DXGIColorFormatInfo struct DXGIColorFormatInfo
...@@ -225,12 +235,6 @@ static bool RequiresFeatureLevel(D3D_FEATURE_LEVEL featureLevel) ...@@ -225,12 +235,6 @@ static bool RequiresFeatureLevel(D3D_FEATURE_LEVEL featureLevel)
return featureLevel >= requiredFeatureLevel; return featureLevel >= requiredFeatureLevel;
} }
ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const
{
FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
}
void AddDXGIFormat(DXGIFormatInfoMap *map, void AddDXGIFormat(DXGIFormatInfoMap *map,
DXGI_FORMAT dxgiFormat, DXGI_FORMAT dxgiFormat,
GLenum componentType, GLenum componentType,
...@@ -260,14 +264,7 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, ...@@ -260,14 +264,7 @@ void AddDXGIFormat(DXGIFormatInfoMap *map,
} }
info.componentType = componentType; info.componentType = componentType;
info.fastCopyFunctions = GetFastCopyFunctionMap(dxgiFormat);
static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap();
std::pair<D3D11FastCopyMap::const_iterator, D3D11FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(dxgiFormat);
for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
{
info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
}
info.nativeMipmapSupport = nativeMipmapSupport; info.nativeMipmapSupport = nativeMipmapSupport;
map->insert(std::make_pair(dxgiFormat, info)); map->insert(std::make_pair(dxgiFormat, info));
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "common/platform.h" #include "common/platform.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h"
namespace rx namespace rx
...@@ -24,7 +25,6 @@ struct Renderer11DeviceCaps; ...@@ -24,7 +25,6 @@ struct Renderer11DeviceCaps;
namespace d3d11 namespace d3d11
{ {
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL); typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL);
struct DXGIFormat struct DXGIFormat
...@@ -45,8 +45,6 @@ struct DXGIFormat ...@@ -45,8 +45,6 @@ struct DXGIFormat
FastCopyFunctionMap fastCopyFunctions; FastCopyFunctionMap fastCopyFunctions;
NativeMipmapGenerationSupportFunction nativeMipmapSupport; NativeMipmapGenerationSupportFunction nativeMipmapSupport;
ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
}; };
// This structure is problematic because a resource is associated with multiple DXGI formats. // This structure is problematic because a resource is associated with multiple DXGI formats.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# Code generation for texture format map # Code generation for texture format map
# #
from datetime import date
import json import json
import math import math
import pprint import pprint
...@@ -39,7 +40,7 @@ enum ANGLEFormat ...@@ -39,7 +40,7 @@ enum ANGLEFormat
template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by gen_texture_format_table.py using data from texture_format_data.json // Generated by gen_texture_format_table.py using data from texture_format_data.json
// //
// Copyright 2015 The ANGLE Project Authors. All rights reserved. // Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -49,10 +50,10 @@ template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. ...@@ -49,10 +50,10 @@ template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/copyimage.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/copyimage.h"
#include "libANGLE/renderer/d3d/generatemip.h" #include "libANGLE/renderer/d3d/generatemip.h"
#include "libANGLE/renderer/d3d/loadimage.h" #include "libANGLE/renderer/d3d/loadimage.h"
...@@ -516,6 +517,7 @@ with open('texture_format_map.json') as texture_format_map_file: ...@@ -516,6 +517,7 @@ with open('texture_format_map.json') as texture_format_map_file:
texture_format_cases = parse_json_into_switch_texture_format_string(json_map, json_data) texture_format_cases = parse_json_into_switch_texture_format_string(json_map, json_data)
angle_format_cases = parse_json_into_switch_angle_format_string(json_data) angle_format_cases = parse_json_into_switch_angle_format_string(json_data)
output_cpp = template_texture_format_table_autogen_cpp.format( output_cpp = template_texture_format_table_autogen_cpp.format(
copyright_year=date.today().year,
texture_format_info_cases=texture_format_cases, texture_format_info_cases=texture_format_cases,
angle_format_info_cases=angle_format_cases) angle_format_info_cases=angle_format_cases)
with open('texture_format_table_autogen.cpp', 'wt') as out_file: with open('texture_format_table_autogen.cpp', 'wt') as out_file:
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/platform.h" #include "common/platform.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h"
......
// GENERATED FILE - DO NOT EDIT. // GENERATED FILE - DO NOT EDIT.
// Generated by gen_texture_format_table.py using data from texture_format_data.json // Generated by gen_texture_format_table.py using data from texture_format_data.json
// //
// Copyright 2015 The ANGLE Project Authors. All rights reserved. // Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/copyimage.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/copyimage.h"
#include "libANGLE/renderer/d3d/generatemip.h" #include "libANGLE/renderer/d3d/generatemip.h"
#include "libANGLE/renderer/d3d/loadimage.h" #include "libANGLE/renderer/d3d/loadimage.h"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/Texture.h" #include "libANGLE/Texture.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/TextureD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
...@@ -187,72 +188,27 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, ...@@ -187,72 +188,27 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target.");
} }
uint8_t *source; uint8_t *source = reinterpret_cast<uint8_t *>(lock.pBits);
int inputPitch; int inputPitch = lock.Pitch;
if (pack.reverseRowOrder)
{
source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
inputPitch = -lock.Pitch;
}
else
{
source = reinterpret_cast<uint8_t*>(lock.pBits);
inputPitch = lock.Pitch;
}
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat);
if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) gl::FormatType formatType(format, type);
{ ColorReadFunction colorReadFunction = d3dFormatInfo.colorReadFunction;
// Direct copy possible
for (int y = 0; y < rect.bottom - rect.top; y++) // TODO(jmadill): Maybe we can avoid a copy of pack parameters here?
{ PackPixelsParams packParams;
memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes); packParams.area.x = rect.left;
} packParams.area.y = rect.top;
} packParams.area.width = rect.right - rect.left;
else packParams.area.height = rect.bottom - rect.top;
{ packParams.format = format;
const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); packParams.type = type;
ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type); packParams.outputPitch = static_cast<GLuint>(outputPitch);
packParams.pack = pack;
GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(format, type);
const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); PackPixels(packParams, sourceFormatInfo, d3dFormatInfo.fastCopyFunctions, colorReadFunction,
inputPitch, source, pixels);
if (fastCopyFunc)
{
// Fast copy is possible through some special function
for (int y = 0; y < rect.bottom - rect.top; y++)
{
for (int x = 0; x < rect.right - rect.left; x++)
{
uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
fastCopyFunc(src, dest);
}
}
}
else
{
ColorReadFunction colorReadFunction = sourceD3DFormatInfo.colorReadFunction;
ColorWriteFunction colorWriteFunction = GetColorWriteFunction(format, type);
uint8_t temp[sizeof(gl::ColorF)];
for (int y = 0; y < rect.bottom - rect.top; y++)
{
for (int x = 0; x < rect.right - rect.left; x++)
{
uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
colorReadFunction(src, temp);
colorWriteFunction(temp, dest);
}
}
}
}
systemSurface->UnlockRect(); systemSurface->UnlockRect();
SafeRelease(systemSurface); SafeRelease(systemSurface);
...@@ -454,4 +410,4 @@ GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *render ...@@ -454,4 +410,4 @@ GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *render
return d3dFormatInfo.internalFormat; return d3dFormatInfo.internalFormat;
} }
} } // namespace rx
...@@ -7,8 +7,9 @@ ...@@ -7,8 +7,9 @@
// formatutils9.cpp: Queries for GL image formats and their translations to D3D9 // formatutils9.cpp: Queries for GL image formats and their translations to D3D9
// formats. // formats.
#include "libANGLE/renderer/d3d/copyimage.h"
#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
#include "libANGLE/renderer/copyimage.h"
#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
#include "libANGLE/renderer/d3d/generatemip.h" #include "libANGLE/renderer/d3d/generatemip.h"
...@@ -39,15 +40,25 @@ struct D3D9FastCopyFormat ...@@ -39,15 +40,25 @@ struct D3D9FastCopyFormat
} }
}; };
typedef std::multimap<D3DFORMAT, D3D9FastCopyFormat> D3D9FastCopyMap; static const FastCopyFunctionMap &GetFastCopyFunctionMap(D3DFORMAT d3dFormat)
static D3D9FastCopyMap BuildFastCopyMap()
{ {
D3D9FastCopyMap map; switch (d3dFormat)
{
map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); case D3DFMT_A8R8G8B8:
{
return map; static FastCopyFunctionMap fastCopyMap;
if (fastCopyMap.empty())
{
fastCopyMap[gl::FormatType(GL_RGBA, GL_UNSIGNED_BYTE)] = CopyBGRA8ToRGBA8;
}
return fastCopyMap;
}
default:
{
static FastCopyFunctionMap emptyMap;
return emptyMap;
}
}
} }
// A map to determine the pixel size and mip generation function of a given D3D format // A map to determine the pixel size and mip generation function of a given D3D format
...@@ -71,12 +82,6 @@ D3DFormat::D3DFormat() ...@@ -71,12 +82,6 @@ D3DFormat::D3DFormat()
{ {
} }
ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const
{
FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type));
return (iter != fastCopyFunctions.end()) ? iter->second : NULL;
}
static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth,
GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits, GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits,
GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits, GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits,
...@@ -97,13 +102,7 @@ static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, ...@@ -97,13 +102,7 @@ static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format,
info.internalFormat = internalFormat; info.internalFormat = internalFormat;
info.mipGenerationFunction = mipFunc; info.mipGenerationFunction = mipFunc;
info.colorReadFunction = colorReadFunc; info.colorReadFunction = colorReadFunc;
info.fastCopyFunctions = GetFastCopyFunctionMap(format);
static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap();
std::pair<D3D9FastCopyMap::const_iterator, D3D9FastCopyMap::const_iterator> fastCopyIter = fastCopyMap.equal_range(format);
for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++)
{
info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction));
}
map->insert(std::make_pair(format, info)); map->insert(std::make_pair(format, info));
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "common/platform.h" #include "common/platform.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/d3d/formatutilsD3D.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h"
namespace rx namespace rx
...@@ -25,8 +26,6 @@ class Renderer9; ...@@ -25,8 +26,6 @@ class Renderer9;
namespace d3d9 namespace d3d9
{ {
typedef std::map<std::pair<GLenum, GLenum>, ColorCopyFunction> FastCopyFunctionMap;
struct D3DFormat struct D3DFormat
{ {
D3DFormat(); D3DFormat();
...@@ -50,8 +49,8 @@ struct D3DFormat ...@@ -50,8 +49,8 @@ struct D3DFormat
ColorReadFunction colorReadFunction; ColorReadFunction colorReadFunction;
FastCopyFunctionMap fastCopyFunctions; FastCopyFunctionMap fastCopyFunctions;
ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const;
}; };
const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); const D3DFormat &GetD3DFormatInfo(D3DFORMAT format);
struct VertexFormat struct VertexFormat
......
...@@ -15,9 +15,15 @@ ...@@ -15,9 +15,15 @@
#include <cstddef> #include <cstddef>
#include <stdint.h> #include <stdint.h>
namespace rx #include <map>
namespace gl
{ {
struct FormatType;
}
namespace rx
{
typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch, const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
uint8_t *destData, size_t destRowPitch, size_t destDepthPitch); uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
...@@ -29,10 +35,6 @@ typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth, ...@@ -29,10 +35,6 @@ typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth,
typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth, typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output); typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
enum VertexConversionType enum VertexConversionType
...@@ -42,9 +44,6 @@ enum VertexConversionType ...@@ -42,9 +44,6 @@ enum VertexConversionType
VERTEX_CONVERT_GPU = 2, VERTEX_CONVERT_GPU = 2,
VERTEX_CONVERT_BOTH = 3 VERTEX_CONVERT_BOTH = 3
}; };
} // namespace rx
ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type);
}
#endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_ #endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
#ifndef LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ #ifndef LIBANGLE_RENDERER_D3D_GENERATEMIP_H_
#define LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ #define LIBANGLE_RENDERER_D3D_GENERATEMIP_H_
#include "libANGLE/renderer/d3d/imageformats.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/renderer/imageformats.h"
namespace rx namespace rx
{ {
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
// loadimage.h: Defines image loading functions // loadimage.h: Defines image loading functions
#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ #ifndef LIBANGLE_RENDERER_LOADIMAGE_H_
#define LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ #define LIBANGLE_RENDERER_LOADIMAGE_H_
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
...@@ -198,4 +198,4 @@ inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_ ...@@ -198,4 +198,4 @@ inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_
#include "loadimage.inl" #include "loadimage.inl"
#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ #endif // LIBANGLE_RENDERER_LOADIMAGE_H_
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
#include "libANGLE/renderer/d3d/loadimage_etc.h" #include "libANGLE/renderer/d3d/loadimage_etc.h"
#include "libANGLE/renderer/imageformats.h"
#include "libANGLE/renderer/d3d/loadimage.h" #include "libANGLE/renderer/d3d/loadimage.h"
#include "libANGLE/renderer/d3d/imageformats.h"
namespace rx namespace rx
{ {
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
// imageformats.h: Defines image format types with functions for mip generation // imageformats.h: Defines image format types with functions for mip generation
// and copying. // and copying.
#ifndef LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_ #ifndef LIBANGLE_RENDERER_IMAGEFORMATS_H_
#define LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_ #define LIBANGLE_RENDERER_IMAGEFORMATS_H_
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
...@@ -28,10 +28,10 @@ struct L8 ...@@ -28,10 +28,10 @@ struct L8
static void readColor(gl::ColorF *dst, const L8 *src) static void readColor(gl::ColorF *dst, const L8 *src)
{ {
const float lum = gl::normalizedToFloat(src->L); const float lum = gl::normalizedToFloat(src->L);
dst->red = lum; dst->red = lum;
dst->green = lum; dst->green = lum;
dst->blue = lum; dst->blue = lum;
dst->alpha = 1.0f; dst->alpha = 1.0f;
} }
static void writeColor(L8 *dst, const gl::ColorF *src) static void writeColor(L8 *dst, const gl::ColorF *src)
...@@ -112,10 +112,10 @@ struct L8A8 ...@@ -112,10 +112,10 @@ struct L8A8
static void readColor(gl::ColorF *dst, const L8A8 *src) static void readColor(gl::ColorF *dst, const L8A8 *src)
{ {
const float lum = gl::normalizedToFloat(src->L); const float lum = gl::normalizedToFloat(src->L);
dst->red = lum; dst->red = lum;
dst->green = lum; dst->green = lum;
dst->blue = lum; dst->blue = lum;
dst->alpha = gl::normalizedToFloat(src->A); dst->alpha = gl::normalizedToFloat(src->A);
} }
static void writeColor(L8A8 *dst, const gl::ColorF *src) static void writeColor(L8A8 *dst, const gl::ColorF *src)
...@@ -126,7 +126,9 @@ struct L8A8 ...@@ -126,7 +126,9 @@ struct L8A8
static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2)
{ {
*(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); *(unsigned short *)dst =
(((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) +
(*(unsigned short *)src1 & *(unsigned short *)src2);
} }
}; };
...@@ -138,10 +140,10 @@ struct A8L8 ...@@ -138,10 +140,10 @@ struct A8L8
static void readColor(gl::ColorF *dst, const A8L8 *src) static void readColor(gl::ColorF *dst, const A8L8 *src)
{ {
const float lum = gl::normalizedToFloat(src->L); const float lum = gl::normalizedToFloat(src->L);
dst->red = lum; dst->red = lum;
dst->green = lum; dst->green = lum;
dst->blue = lum; dst->blue = lum;
dst->alpha = gl::normalizedToFloat(src->A); dst->alpha = gl::normalizedToFloat(src->A);
} }
static void writeColor(A8L8 *dst, const gl::ColorF *src) static void writeColor(A8L8 *dst, const gl::ColorF *src)
...@@ -152,7 +154,9 @@ struct A8L8 ...@@ -152,7 +154,9 @@ struct A8L8
static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2)
{ {
*(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); *(unsigned short *)dst =
(((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) +
(*(unsigned short *)src1 & *(unsigned short *)src2);
} }
}; };
...@@ -191,7 +195,9 @@ struct R8G8 ...@@ -191,7 +195,9 @@ struct R8G8
static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2)
{ {
*(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); *(unsigned short *)dst =
(((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) +
(*(unsigned short *)src1 & *(unsigned short *)src2);
} }
}; };
...@@ -285,30 +291,35 @@ struct B8G8R8 ...@@ -285,30 +291,35 @@ struct B8G8R8
struct R5G6B5 struct R5G6B5
{ {
// OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the
// bits of the bitfield, and successive component occupying progressively less significant locations" // most significant
// bits of the bitfield, and successive component occupying progressively less significant
// locations"
unsigned short RGB; unsigned short RGB;
static void readColor(gl::ColorF *dst, const R5G6B5 *src) static void readColor(gl::ColorF *dst, const R5G6B5 *src)
{ {
dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB));
dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB));
dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB));
dst->alpha = 1.0f; dst->alpha = 1.0f;
} }
static void writeColor(R5G6B5 *dst, const gl::ColorF *src) static void writeColor(R5G6B5 *dst, const gl::ColorF *src)
{ {
dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) |
gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) |
gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue));
} }
static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2)
{ {
dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), gl::getShiftedData<5, 11>(src2->RGB))) | dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB),
gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), gl::getShiftedData<6, 5>(src2->RGB))) | gl::getShiftedData<5, 11>(src2->RGB))) |
gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), gl::getShiftedData<5, 0>(src2->RGB))); gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB),
gl::getShiftedData<6, 5>(src2->RGB))) |
gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB),
gl::getShiftedData<5, 0>(src2->RGB)));
} }
}; };
...@@ -353,7 +364,9 @@ struct A8R8G8B8 ...@@ -353,7 +364,9 @@ struct A8R8G8B8
static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2)
{ {
*(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); *(unsigned int *)dst =
(((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) +
(*(unsigned int *)src1 & *(unsigned int *)src2);
} }
}; };
...@@ -398,7 +411,9 @@ struct R8G8B8A8 ...@@ -398,7 +411,9 @@ struct R8G8B8A8
static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2)
{ {
*(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); *(unsigned int *)dst =
(((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) +
(*(unsigned int *)src1 & *(unsigned int *)src2);
} }
}; };
...@@ -443,7 +458,9 @@ struct B8G8R8A8 ...@@ -443,7 +458,9 @@ struct B8G8R8A8
static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2)
{ {
*(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); *(unsigned int *)dst =
(((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) +
(*(unsigned int *)src1 & *(unsigned int *)src2);
} }
}; };
...@@ -456,17 +473,17 @@ struct B8G8R8X8 ...@@ -456,17 +473,17 @@ struct B8G8R8X8
static void readColor(gl::ColorF *dst, const B8G8R8X8 *src) static void readColor(gl::ColorF *dst, const B8G8R8X8 *src)
{ {
dst->red = gl::normalizedToFloat(src->R); dst->red = gl::normalizedToFloat(src->R);
dst->green = gl::normalizedToFloat(src->G); dst->green = gl::normalizedToFloat(src->G);
dst->blue = gl::normalizedToFloat(src->B); dst->blue = gl::normalizedToFloat(src->B);
dst->alpha = 1.0f; dst->alpha = 1.0f;
} }
static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src) static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src)
{ {
dst->red = src->R; dst->red = src->R;
dst->green = src->G; dst->green = src->G;
dst->blue = src->B; dst->blue = src->B;
dst->alpha = 1; dst->alpha = 1;
} }
...@@ -488,7 +505,9 @@ struct B8G8R8X8 ...@@ -488,7 +505,9 @@ struct B8G8R8X8
static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2)
{ {
*(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); *(unsigned int *)dst =
(((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) +
(*(unsigned int *)src1 & *(unsigned int *)src2);
dst->X = 255; dst->X = 255;
} }
}; };
...@@ -501,86 +520,102 @@ struct A1R5G5B5 ...@@ -501,86 +520,102 @@ struct A1R5G5B5
{ {
dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB));
dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB));
dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB));
dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB));
} }
static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src) static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src)
{ {
dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) |
gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) | gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) |
gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) |
gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue));
} }
static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2)
{ {
dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), gl::getShiftedData<1, 15>(src2->ARGB))) | dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB),
gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), gl::getShiftedData<5, 10>(src2->ARGB))) | gl::getShiftedData<1, 15>(src2->ARGB))) |
gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), gl::getShiftedData<5, 5>(src2->ARGB))) | gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB),
gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), gl::getShiftedData<5, 0>(src2->ARGB))); gl::getShiftedData<5, 10>(src2->ARGB))) |
gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB),
gl::getShiftedData<5, 5>(src2->ARGB))) |
gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB),
gl::getShiftedData<5, 0>(src2->ARGB)));
} }
}; };
struct R5G5B5A1 struct R5G5B5A1
{ {
// OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the
// bits of the bitfield, and successive component occupying progressively less significant locations" // most significant
// bits of the bitfield, and successive component occupying progressively less significant
// locations"
unsigned short RGBA; unsigned short RGBA;
static void readColor(gl::ColorF *dst, const R5G5B5A1 *src) static void readColor(gl::ColorF *dst, const R5G5B5A1 *src)
{ {
dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA));
dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA));
dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA));
dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA));
} }
static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src) static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src)
{ {
dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) |
gl::shiftData<5, 6>(gl::floatToNormalized<5, unsigned short>(src->green)) | gl::shiftData<5, 6>(gl::floatToNormalized<5, unsigned short>(src->green)) |
gl::shiftData<5, 1>(gl::floatToNormalized<5, unsigned short>(src->blue)) | gl::shiftData<5, 1>(gl::floatToNormalized<5, unsigned short>(src->blue)) |
gl::shiftData<1, 0>(gl::floatToNormalized<1, unsigned short>(src->alpha)); gl::shiftData<1, 0>(gl::floatToNormalized<1, unsigned short>(src->alpha));
} }
static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2)
{ {
dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), gl::getShiftedData<5, 11>(src2->RGBA))) | dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA),
gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), gl::getShiftedData<5, 6>(src2->RGBA))) | gl::getShiftedData<5, 11>(src2->RGBA))) |
gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), gl::getShiftedData<5, 1>(src2->RGBA))) | gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA),
gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), gl::getShiftedData<1, 0>(src2->RGBA))); gl::getShiftedData<5, 6>(src2->RGBA))) |
gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA),
gl::getShiftedData<5, 1>(src2->RGBA))) |
gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA),
gl::getShiftedData<1, 0>(src2->RGBA)));
} }
}; };
struct R4G4B4A4 struct R4G4B4A4
{ {
// OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the
// bits of the bitfield, and successive component occupying progressively less significant locations" // most significant
// bits of the bitfield, and successive component occupying progressively less significant
// locations"
unsigned short RGBA; unsigned short RGBA;
static void readColor(gl::ColorF *dst, const R4G4B4A4 *src) static void readColor(gl::ColorF *dst, const R4G4B4A4 *src)
{ {
dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA));
dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA));
dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA));
dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA));
} }
static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src) static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src)
{ {
dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->red)) | dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->red)) |
gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->green)) | gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->green)) |
gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->blue)) | gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->blue)) |
gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->alpha)); gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->alpha));
} }
static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2)
{ {
dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), gl::getShiftedData<4, 12>(src2->RGBA))) | dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA),
gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), gl::getShiftedData<4, 8>(src2->RGBA))) | gl::getShiftedData<4, 12>(src2->RGBA))) |
gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), gl::getShiftedData<4, 4>(src2->RGBA))) | gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA),
gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), gl::getShiftedData<4, 0>(src2->RGBA))); gl::getShiftedData<4, 8>(src2->RGBA))) |
gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA),
gl::getShiftedData<4, 4>(src2->RGBA))) |
gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA),
gl::getShiftedData<4, 0>(src2->RGBA)));
} }
}; };
...@@ -591,25 +626,29 @@ struct A4R4G4B4 ...@@ -591,25 +626,29 @@ struct A4R4G4B4
static void readColor(gl::ColorF *dst, const A4R4G4B4 *src) static void readColor(gl::ColorF *dst, const A4R4G4B4 *src)
{ {
dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB));
dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB));
dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB));
dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB));
} }
static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src) static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src)
{ {
dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->alpha)) | dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->alpha)) |
gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->red)) | gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->red)) |
gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->green)) | gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->green)) |
gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->blue)); gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->blue));
} }
static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2)
{ {
dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), gl::getShiftedData<4, 12>(src2->ARGB))) | dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB),
gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), gl::getShiftedData<4, 8>(src2->ARGB))) | gl::getShiftedData<4, 12>(src2->ARGB))) |
gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), gl::getShiftedData<4, 4>(src2->ARGB))) | gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB),
gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), gl::getShiftedData<4, 0>(src2->ARGB))); gl::getShiftedData<4, 8>(src2->ARGB))) |
gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB),
gl::getShiftedData<4, 4>(src2->ARGB))) |
gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB),
gl::getShiftedData<4, 0>(src2->ARGB)));
} }
}; };
...@@ -664,7 +703,7 @@ struct R16G16 ...@@ -664,7 +703,7 @@ struct R16G16
static void readColor(gl::ColorUI *dst, const R16G16 *src) static void readColor(gl::ColorUI *dst, const R16G16 *src)
{ {
dst->red = src->R; dst->red = src->R;
dst->green = src->G; dst->green = src->G;
dst->blue = 0; dst->blue = 0;
dst->alpha = 1; dst->alpha = 1;
...@@ -1533,7 +1572,7 @@ struct R16F ...@@ -1533,7 +1572,7 @@ struct R16F
{ {
dst->R = gl::float32ToFloat16(src->red); dst->R = gl::float32ToFloat16(src->red);
} }
static void average(R16F *dst, const R16F *src1, const R16F *src2) static void average(R16F *dst, const R16F *src1, const R16F *src2)
{ {
dst->R = gl::averageHalfFloat(src1->R, src2->R); dst->R = gl::averageHalfFloat(src1->R, src2->R);
...@@ -1569,7 +1608,7 @@ struct L16F ...@@ -1569,7 +1608,7 @@ struct L16F
static void readColor(gl::ColorF *dst, const L16F *src) static void readColor(gl::ColorF *dst, const L16F *src)
{ {
float lum = gl::float16ToFloat32(src->L); float lum = gl::float16ToFloat32(src->L);
dst->red = lum; dst->red = lum;
dst->green = lum; dst->green = lum;
dst->blue = lum; dst->blue = lum;
...@@ -1594,7 +1633,7 @@ struct L16A16F ...@@ -1594,7 +1633,7 @@ struct L16A16F
static void readColor(gl::ColorF *dst, const L16A16F *src) static void readColor(gl::ColorF *dst, const L16A16F *src)
{ {
float lum = gl::float16ToFloat32(src->L); float lum = gl::float16ToFloat32(src->L);
dst->red = lum; dst->red = lum;
dst->green = lum; dst->green = lum;
dst->blue = lum; dst->blue = lum;
...@@ -1745,10 +1784,7 @@ struct R32F ...@@ -1745,10 +1784,7 @@ struct R32F
dst->alpha = 1.0f; dst->alpha = 1.0f;
} }
static void writeColor(R32F *dst, const gl::ColorF *src) static void writeColor(R32F *dst, const gl::ColorF *src) { dst->R = src->red; }
{
dst->R = src->red;
}
static void average(R32F *dst, const R32F *src1, const R32F *src2) static void average(R32F *dst, const R32F *src1, const R32F *src2)
{ {
...@@ -1768,10 +1804,7 @@ struct A32F ...@@ -1768,10 +1804,7 @@ struct A32F
dst->alpha = src->A; dst->alpha = src->A;
} }
static void writeColor(A32F *dst, const gl::ColorF *src) static void writeColor(A32F *dst, const gl::ColorF *src) { dst->A = src->alpha; }
{
dst->A = src->alpha;
}
static void average(A32F *dst, const A32F *src1, const A32F *src2) static void average(A32F *dst, const A32F *src1, const A32F *src2)
{ {
...@@ -1895,7 +1928,7 @@ struct R10G10B10A2 ...@@ -1895,7 +1928,7 @@ struct R10G10B10A2
dst->red = gl::normalizedToFloat<10>(src->R); dst->red = gl::normalizedToFloat<10>(src->R);
dst->green = gl::normalizedToFloat<10>(src->G); dst->green = gl::normalizedToFloat<10>(src->G);
dst->blue = gl::normalizedToFloat<10>(src->B); dst->blue = gl::normalizedToFloat<10>(src->B);
dst->alpha = gl::normalizedToFloat< 2>(src->A); dst->alpha = gl::normalizedToFloat<2>(src->A);
} }
static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src) static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src)
...@@ -1911,7 +1944,7 @@ struct R10G10B10A2 ...@@ -1911,7 +1944,7 @@ struct R10G10B10A2
dst->R = gl::floatToNormalized<10, unsigned int>(src->red); dst->R = gl::floatToNormalized<10, unsigned int>(src->red);
dst->G = gl::floatToNormalized<10, unsigned int>(src->green); dst->G = gl::floatToNormalized<10, unsigned int>(src->green);
dst->B = gl::floatToNormalized<10, unsigned int>(src->blue); dst->B = gl::floatToNormalized<10, unsigned int>(src->blue);
dst->A = gl::floatToNormalized< 2, unsigned int>(src->alpha); dst->A = gl::floatToNormalized<2, unsigned int>(src->alpha);
} }
static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src)
...@@ -1940,28 +1973,27 @@ struct R9G9B9E5 ...@@ -1940,28 +1973,27 @@ struct R9G9B9E5
static void readColor(gl::ColorF *dst, const R9G9B9E5 *src) static void readColor(gl::ColorF *dst, const R9G9B9E5 *src)
{ {
gl::convert999E5toRGBFloats(gl::bitCast<unsigned int>(*src), &dst->red, &dst->green, &dst->blue); gl::convert999E5toRGBFloats(gl::bitCast<unsigned int>(*src), &dst->red, &dst->green,
&dst->blue);
dst->alpha = 1.0f; dst->alpha = 1.0f;
} }
static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src) static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src)
{ {
*reinterpret_cast<unsigned int*>(dst) = gl::convertRGBFloatsTo999E5(src->red, *reinterpret_cast<unsigned int *>(dst) =
src->green, gl::convertRGBFloatsTo999E5(src->red, src->green, src->blue);
src->blue);
} }
static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2)
{ {
float r1, g1, b1; float r1, g1, b1;
gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int*>(src1), &r1, &g1, &b1); gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int *>(src1), &r1, &g1, &b1);
float r2, g2, b2; float r2, g2, b2;
gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int*>(src2), &r2, &g2, &b2); gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int *>(src2), &r2, &g2, &b2);
*reinterpret_cast<unsigned int*>(dst) = gl::convertRGBFloatsTo999E5(gl::average(r1, r2), *reinterpret_cast<unsigned int *>(dst) = gl::convertRGBFloatsTo999E5(
gl::average(g1, g2), gl::average(r1, r2), gl::average(g1, g2), gl::average(b1, b2));
gl::average(b1, b2));
} }
}; };
...@@ -1993,7 +2025,6 @@ struct R11G11B10F ...@@ -1993,7 +2025,6 @@ struct R11G11B10F
dst->B = gl::averageFloat10(src1->B, src2->B); dst->B = gl::averageFloat10(src1->B, src2->B);
} }
}; };
} // namespace rx
} #endif // LIBANGLE_RENDERER_IMAGEFORMATS_H_
#endif // LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_
// //
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. // Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// renderer_utils:
// Helper methods pertaining to most or all back-ends.
//
// formatutils9.cpp: Queries for GL image formats and their translations to D3D #include "libANGLE/renderer/renderer_utils.h"
// formats.
#include "libANGLE/renderer/d3d/formatutilsD3D.h"
#include <map>
#include "common/debug.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/imageformats.h" #include "libANGLE/renderer/copyimage.h"
#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/imageformats.h"
namespace rx namespace rx
{ {
typedef std::pair<GLenum, GLenum> FormatTypePair; namespace
typedef std::pair<FormatTypePair, ColorWriteFunction> FormatWriteFunctionPair; {
typedef std::map<FormatTypePair, ColorWriteFunction> FormatWriteFunctionMap; typedef std::pair<gl::FormatType, ColorWriteFunction> FormatWriteFunctionPair;
typedef std::map<gl::FormatType, ColorWriteFunction> FormatWriteFunctionMap;
static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map, GLenum format, GLenum type, static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map,
GLenum format,
GLenum type,
ColorWriteFunction writeFunc) ColorWriteFunction writeFunc)
{ {
map->insert(FormatWriteFunctionPair(FormatTypePair(format, type), writeFunc)); map->insert(FormatWriteFunctionPair(gl::FormatType(format, type), writeFunc));
} }
static FormatWriteFunctionMap BuildFormatWriteFunctionMap() static FormatWriteFunctionMap BuildFormatWriteFunctionMap()
{ {
FormatWriteFunctionMap map; FormatWriteFunctionMap map;
// clang-format off
// | Format | Type | Color write function | // | Format | Type | Color write function |
InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, WriteColor<R8G8B8A8, GLfloat> ); InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, WriteColor<R8G8B8A8, GLfloat> );
InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_BYTE, WriteColor<R8G8B8A8S, GLfloat> ); InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_BYTE, WriteColor<R8G8B8A8S, GLfloat> );
...@@ -135,14 +137,112 @@ static FormatWriteFunctionMap BuildFormatWriteFunctionMap() ...@@ -135,14 +137,112 @@ static FormatWriteFunctionMap BuildFormatWriteFunctionMap()
InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL ); InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL );
InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL ); InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL );
// clang-format on
return map; return map;
} }
} // anonymous namespace
ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type) PackPixelsParams::PackPixelsParams()
: format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0)
{
}
PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
GLenum formatIn,
GLenum typeIn,
GLuint outputPitchIn,
const gl::PixelPackState &packIn,
ptrdiff_t offsetIn)
: area(areaIn),
format(formatIn),
type(typeIn),
outputPitch(outputPitchIn),
packBuffer(packIn.pixelBuffer.get()),
pack(packIn.alignment, packIn.reverseRowOrder),
offset(offsetIn)
{
}
void PackPixels(const PackPixelsParams &params,
const gl::InternalFormat &sourceFormatInfo,
const FastCopyFunctionMap &fastCopyFunctionsMap,
ColorReadFunction colorReadFunction,
int inputPitchIn,
const uint8_t *sourceIn,
uint8_t *destWithoutOffset)
{
uint8_t *destWithOffset = destWithoutOffset + params.offset;
const uint8_t *source = sourceIn;
int inputPitch = inputPitchIn;
if (params.pack.reverseRowOrder)
{
source += inputPitch * (params.area.height - 1);
inputPitch = -inputPitch;
}
if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type)
{
// Direct copy possible
for (int y = 0; y < params.area.height; ++y)
{
memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch,
params.area.width * sourceFormatInfo.pixelBytes);
}
return;
}
gl::FormatType formatType(params.format, params.type);
ColorCopyFunction fastCopyFunc = GetFastCopyFunction(fastCopyFunctionsMap, formatType);
GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(formatType.format, formatType.type);
const auto &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
if (fastCopyFunc)
{
// Fast copy is possible through some special function
for (int y = 0; y < params.area.height; ++y)
{
for (int x = 0; x < params.area.width; ++x)
{
uint8_t *dest =
destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
fastCopyFunc(src, dest);
}
}
return;
}
ColorWriteFunction colorWriteFunction = GetColorWriteFunction(formatType);
// Maximum size of any Color<T> type used.
uint8_t temp[16];
static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) &&
sizeof(temp) >= sizeof(gl::ColorI),
"Unexpected size of gl::Color struct.");
for (int y = 0; y < params.area.height; ++y)
{
for (int x = 0; x < params.area.width; ++x)
{
uint8_t *dest = destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
colorReadFunction(src, temp);
colorWriteFunction(temp, dest);
}
}
}
ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType)
{ {
static const FormatWriteFunctionMap formatTypeMap = BuildFormatWriteFunctionMap(); static const FormatWriteFunctionMap formatTypeMap = BuildFormatWriteFunctionMap();
FormatWriteFunctionMap::const_iterator iter = formatTypeMap.find(FormatTypePair(format, type)); auto iter = formatTypeMap.find(formatType);
ASSERT(iter != formatTypeMap.end()); ASSERT(iter != formatTypeMap.end());
if (iter != formatTypeMap.end()) if (iter != formatTypeMap.end())
{ {
...@@ -150,8 +250,15 @@ ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type) ...@@ -150,8 +250,15 @@ ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
} }
else else
{ {
return NULL; return nullptr;
} }
} }
ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions,
const gl::FormatType &formatType)
{
auto iter = fastCopyFunctions.find(formatType);
return (iter != fastCopyFunctions.end()) ? iter->second : nullptr;
} }
} // namespace rx
//
// Copyright 2016 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.
//
// renderer_utils:
// Helper methods pertaining to most or all back-ends.
//
#ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
#define LIBANGLE_RENDERER_RENDERER_UTILS_H_
#include <cstdint>
#include <map>
#include "libANGLE/angletypes.h"
namespace gl
{
struct FormatType;
struct InternalFormat;
}
namespace rx
{
typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
typedef std::map<gl::FormatType, ColorCopyFunction> FastCopyFunctionMap;
struct PackPixelsParams
{
PackPixelsParams();
PackPixelsParams(const gl::Rectangle &area,
GLenum format,
GLenum type,
GLuint outputPitch,
const gl::PixelPackState &pack,
ptrdiff_t offset);
gl::Rectangle area;
GLenum format;
GLenum type;
GLuint outputPitch;
gl::Buffer *packBuffer;
gl::PixelPackState pack;
ptrdiff_t offset;
};
void PackPixels(const PackPixelsParams &params,
const gl::InternalFormat &sourceFormatInfo,
const FastCopyFunctionMap &fastCopyFunctionsMap,
ColorReadFunction colorReadFunction,
int inputPitch,
const uint8_t *source,
uint8_t *destination);
ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType);
ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions,
const gl::FormatType &formatType);
} // namespace rx
#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_
...@@ -166,6 +166,12 @@ ...@@ -166,6 +166,12 @@
'libANGLE/renderer/TextureImpl.h', 'libANGLE/renderer/TextureImpl.h',
'libANGLE/renderer/TransformFeedbackImpl.h', 'libANGLE/renderer/TransformFeedbackImpl.h',
'libANGLE/renderer/VertexArrayImpl.h', 'libANGLE/renderer/VertexArrayImpl.h',
'libANGLE/renderer/copyimage.cpp',
'libANGLE/renderer/copyimage.h',
'libANGLE/renderer/copyimage.inl',
'libANGLE/renderer/imageformats.h',
'libANGLE/renderer/renderer_utils.cpp',
'libANGLE/renderer/renderer_utils.h',
'libANGLE/validationEGL.cpp', 'libANGLE/validationEGL.cpp',
'libANGLE/validationEGL.h', 'libANGLE/validationEGL.h',
'libANGLE/validationES.cpp', 'libANGLE/validationES.cpp',
...@@ -183,9 +189,6 @@ ...@@ -183,9 +189,6 @@
'libANGLE/renderer/d3d/BufferD3D.h', 'libANGLE/renderer/d3d/BufferD3D.h',
'libANGLE/renderer/d3d/CompilerD3D.cpp', 'libANGLE/renderer/d3d/CompilerD3D.cpp',
'libANGLE/renderer/d3d/CompilerD3D.h', 'libANGLE/renderer/d3d/CompilerD3D.h',
'libANGLE/renderer/d3d/copyimage.cpp',
'libANGLE/renderer/d3d/copyimage.h',
'libANGLE/renderer/d3d/copyimage.inl',
'libANGLE/renderer/d3d/DeviceD3D.cpp', 'libANGLE/renderer/d3d/DeviceD3D.cpp',
'libANGLE/renderer/d3d/DeviceD3D.h', 'libANGLE/renderer/d3d/DeviceD3D.h',
'libANGLE/renderer/d3d/DisplayD3D.cpp', 'libANGLE/renderer/d3d/DisplayD3D.cpp',
...@@ -194,7 +197,6 @@ ...@@ -194,7 +197,6 @@
'libANGLE/renderer/d3d/DynamicHLSL.h', 'libANGLE/renderer/d3d/DynamicHLSL.h',
'libANGLE/renderer/d3d/EGLImageD3D.cpp', 'libANGLE/renderer/d3d/EGLImageD3D.cpp',
'libANGLE/renderer/d3d/EGLImageD3D.h', 'libANGLE/renderer/d3d/EGLImageD3D.h',
'libANGLE/renderer/d3d/formatutilsD3D.cpp',
'libANGLE/renderer/d3d/formatutilsD3D.h', 'libANGLE/renderer/d3d/formatutilsD3D.h',
'libANGLE/renderer/d3d/FramebufferD3D.cpp', 'libANGLE/renderer/d3d/FramebufferD3D.cpp',
'libANGLE/renderer/d3d/FramebufferD3D.h', 'libANGLE/renderer/d3d/FramebufferD3D.h',
...@@ -204,7 +206,6 @@ ...@@ -204,7 +206,6 @@
'libANGLE/renderer/d3d/HLSLCompiler.h', 'libANGLE/renderer/d3d/HLSLCompiler.h',
'libANGLE/renderer/d3d/ImageD3D.cpp', 'libANGLE/renderer/d3d/ImageD3D.cpp',
'libANGLE/renderer/d3d/ImageD3D.h', 'libANGLE/renderer/d3d/ImageD3D.h',
'libANGLE/renderer/d3d/imageformats.h',
'libANGLE/renderer/d3d/IndexBuffer.cpp', 'libANGLE/renderer/d3d/IndexBuffer.cpp',
'libANGLE/renderer/d3d/IndexBuffer.h', 'libANGLE/renderer/d3d/IndexBuffer.h',
'libANGLE/renderer/d3d/IndexDataManager.cpp', 'libANGLE/renderer/d3d/IndexDataManager.cpp',
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "libANGLE/renderer/d3d/imageformats.h" #include "libANGLE/renderer/imageformats.h"
using namespace angle; using namespace angle;
......
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