Commit 0ecb18b9 by John Bauman Committed by Commit Bot

Avoid a copy in TextureStorage11::setData

This is essentially a reland of 9cf9bcbe This code always allocates a new memory buffer for the texture memory, picks a load function to copy/convert the input data into it, and the uploads. In the case where the input format matches the upload format we should be able to skip the allocation and copy and be much happier. Change-Id: If4281aeb4cd7bbbebba60122a10610a916833052 Reviewed-on: https://chromium-review.googlesource.com/326852 Tryjob-Request: John Bauman <jbauman@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: John Bauman <jbauman@chromium.org>
parent 0dcaaf77
...@@ -256,7 +256,7 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp ...@@ -256,7 +256,7 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type).loadFunction;
D3D11_MAPPED_SUBRESOURCE mappedImage; D3D11_MAPPED_SUBRESOURCE mappedImage;
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
...@@ -291,7 +291,7 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) ...@@ -291,7 +291,7 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input)
ASSERT(area.y % outputBlockHeight == 0); ASSERT(area.y % outputBlockHeight == 0);
const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE).loadFunction;
D3D11_MAPPED_SUBRESOURCE mappedImage; D3D11_MAPPED_SUBRESOURCE mappedImage;
gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
......
...@@ -664,17 +664,29 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image ...@@ -664,17 +664,29 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image
UINT bufferDepthPitch = bufferRowPitch * height; UINT bufferDepthPitch = bufferRowPitch * height;
size_t neededSize = bufferDepthPitch * depth; size_t neededSize = bufferDepthPitch * depth;
MemoryBuffer *conversionBuffer = NULL; MemoryBuffer *conversionBuffer = nullptr;
error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer); const uint8_t *data = nullptr;
if (error.isError())
d3d11::LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions.at(type);
if (loadFunctionInfo.requiresConversion)
{ {
return error; error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer);
} if (error.isError())
{
return error;
}
// TODO: fast path loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type); srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch, srcDepthPitch, bufferDepthPitch);
conversionBuffer->data(), bufferRowPitch, bufferDepthPitch); data = conversionBuffer->data();
}
else
{
data = pixelData + srcSkipBytes;
bufferRowPitch = srcRowPitch;
bufferDepthPitch = srcDepthPitch;
}
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
...@@ -690,15 +702,13 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image ...@@ -690,15 +702,13 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image
destD3DBox.front = destBox->z; destD3DBox.front = destBox->z;
destD3DBox.back = destBox->z + destBox->depth; destD3DBox.back = destBox->z + destBox->depth;
immediateContext->UpdateSubresource(resource, destSubresource, immediateContext->UpdateSubresource(resource, destSubresource, &destD3DBox, data,
&destD3DBox, conversionBuffer->data(),
bufferRowPitch, bufferDepthPitch); bufferRowPitch, bufferDepthPitch);
} }
else else
{ {
immediateContext->UpdateSubresource(resource, destSubresource, immediateContext->UpdateSubresource(resource, destSubresource, NULL, data, bufferRowPitch,
NULL, conversionBuffer->data(), bufferDepthPitch);
bufferRowPitch, bufferDepthPitch);
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
......
...@@ -22,6 +22,7 @@ template = """// GENERATED FILE - DO NOT EDIT. ...@@ -22,6 +22,7 @@ template = """// GENERATED FILE - DO NOT EDIT.
#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/load_functions_table.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
#include "libANGLE/renderer/d3d/loadimage.h" #include "libANGLE/renderer/d3d/loadimage.h"
#include "libANGLE/renderer/d3d/loadimage_etc.h" #include "libANGLE/renderer/d3d/loadimage_etc.h"
...@@ -70,8 +71,8 @@ void UnreachableLoadFunction(size_t width, ...@@ -70,8 +71,8 @@ void UnreachableLoadFunction(size_t width,
}} // namespace }} // namespace
// TODO we can replace these maps with more generated code // TODO we can replace these maps with more generated code
const std::map<GLenum, LoadImageFunction> &GetLoadFunctionsMap(GLenum {internal_format}, const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum {internal_format},
DXGI_FORMAT {dxgi_format}) DXGI_FORMAT {dxgi_format})
{{ {{
// clang-format off // clang-format off
switch ({internal_format}) switch ({internal_format})
...@@ -79,7 +80,7 @@ const std::map<GLenum, LoadImageFunction> &GetLoadFunctionsMap(GLenum {internal_ ...@@ -79,7 +80,7 @@ const std::map<GLenum, LoadImageFunction> &GetLoadFunctionsMap(GLenum {internal_
{data} {data}
default: default:
{{ {{
static std::map<GLenum, LoadImageFunction> emptyLoadFunctionsMap; static std::map<GLenum, LoadImageFunctionInfo> emptyLoadFunctionsMap;
return emptyLoadFunctionsMap; return emptyLoadFunctionsMap;
}} }}
}} }}
...@@ -96,8 +97,8 @@ internal_format_param = 'internalFormat' ...@@ -96,8 +97,8 @@ internal_format_param = 'internalFormat'
dxgi_format_param = 'dxgiFormat' dxgi_format_param = 'dxgiFormat'
dxgi_format_unknown = "DXGI_FORMAT_UNKNOWN" dxgi_format_unknown = "DXGI_FORMAT_UNKNOWN"
def get_function_maps_string(typestr, function): def get_function_maps_string(typestr, function, requiresConversion):
return ' loadMap[' + typestr + '] = ' + function + ';\n' return ' loadMap[' + typestr + '] = LoadImageFunctionInfo(' + function + ', ' + requiresConversion + ');\n'
def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string): def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string):
if dxgi_unknown_string not in dxgi_to_type_map: if dxgi_unknown_string not in dxgi_to_type_map:
...@@ -106,7 +107,7 @@ def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string): ...@@ -106,7 +107,7 @@ def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string):
table_data = '' table_data = ''
for unknown_type_function in dxgi_to_type_map[dxgi_unknown_string]: for unknown_type_function in dxgi_to_type_map[dxgi_unknown_string]:
table_data += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction']) table_data += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true')
return table_data return table_data
...@@ -125,8 +126,8 @@ def create_dxgi_to_type_map(dst, json_data, internal_format_str): ...@@ -125,8 +126,8 @@ def create_dxgi_to_type_map(dst, json_data, internal_format_str):
def get_load_function_map_snippet(insert_map_string): def get_load_function_map_snippet(insert_map_string):
load_function_map_snippet = '' load_function_map_snippet = ''
load_function_map_snippet += ' static const std::map<GLenum, LoadImageFunction> loadFunctionsMap = []() {\n' load_function_map_snippet += ' static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = []() {\n'
load_function_map_snippet += ' std::map<GLenum, LoadImageFunction> loadMap;\n' load_function_map_snippet += ' std::map<GLenum, LoadImageFunctionInfo> loadMap;\n'
load_function_map_snippet += insert_map_string load_function_map_snippet += insert_map_string
load_function_map_snippet += ' return loadMap;\n' load_function_map_snippet += ' return loadMap;\n'
load_function_map_snippet += ' }();\n\n' load_function_map_snippet += ' }();\n\n'
...@@ -157,8 +158,7 @@ def parse_json_into_switch_string(json_data): ...@@ -157,8 +158,7 @@ def parse_json_into_switch_string(json_data):
insert_map_string = '' insert_map_string = ''
types_already_in_loadmap = set() types_already_in_loadmap = set()
for type_function in sorted(dxgi_format_item[1]): for type_function in sorted(dxgi_format_item[1]):
# type_function['requiresConversion'] element is not in use at the moment but may be needed later insert_map_string += get_function_maps_string(type_function['type'], type_function['loadFunction'], type_function['requiresConversion'])
insert_map_string += get_function_maps_string(type_function['type'], type_function['loadFunction'])
types_already_in_loadmap.add(type_function['type']) types_already_in_loadmap.add(type_function['type'])
# DXGI_FORMAT_UNKNOWN add ons # DXGI_FORMAT_UNKNOWN add ons
...@@ -166,7 +166,7 @@ def parse_json_into_switch_string(json_data): ...@@ -166,7 +166,7 @@ def parse_json_into_switch_string(json_data):
for unknown_type_function in dxgi_to_type_map[dxgi_format_unknown]: for unknown_type_function in dxgi_to_type_map[dxgi_format_unknown]:
# Check that it's not already in the loadmap so it doesn't override the value # Check that it's not already in the loadmap so it doesn't override the value
if unknown_type_function['type'] not in types_already_in_loadmap: if unknown_type_function['type'] not in types_already_in_loadmap:
insert_map_string += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction']) insert_map_string += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true')
table_data += get_load_function_map_snippet(insert_map_string) table_data += get_load_function_map_snippet(insert_map_string)
table_data += ' }\n' table_data += ' }\n'
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <map> #include <map>
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
namespace rx namespace rx
{ {
...@@ -20,8 +21,8 @@ namespace rx ...@@ -20,8 +21,8 @@ namespace rx
namespace d3d11 namespace d3d11
{ {
const std::map<GLenum, LoadImageFunction> &GetLoadFunctionsMap(GLenum internalFormat, const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum internalFormat,
DXGI_FORMAT dxgiFormat); DXGI_FORMAT dxgiFormat);
} // namespace d3d11 } // namespace d3d11
......
...@@ -22,6 +22,18 @@ namespace rx ...@@ -22,6 +22,18 @@ namespace rx
namespace d3d11 namespace d3d11
{ {
struct LoadImageFunctionInfo
{
LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
: loadFunction(loadFunction), requiresConversion(requiresConversion)
{
}
LoadImageFunction loadFunction;
bool requiresConversion;
};
struct TextureFormat struct TextureFormat
{ {
TextureFormat(); TextureFormat();
...@@ -37,7 +49,7 @@ struct TextureFormat ...@@ -37,7 +49,7 @@ struct TextureFormat
DXGI_FORMAT swizzleRTVFormat; DXGI_FORMAT swizzleRTVFormat;
InitializeTextureDataFunction dataInitializerFunction; InitializeTextureDataFunction dataInitializerFunction;
typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap; typedef std::map<GLenum, LoadImageFunctionInfo> LoadFunctionMap;
LoadFunctionMap loadFunctions; LoadFunctionMap loadFunctions;
}; };
...@@ -49,4 +61,4 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalformat, ...@@ -49,4 +61,4 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalformat,
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
\ No newline at end of file
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