Commit c13bda86 by Olli Etuaho Committed by Commit Bot

Use ImmutableString for HLSL texture references

This also adds ImmutableStringBuilder class, which can be used to build ImmutableStrings in place without extra allocations if the maximum length is known in advance. BUG=angleproject:2267 TEST=angle_unittests Change-Id: I4dfb78adeb0cffcfad0d25753fb8063466012c92 Reviewed-on: https://chromium-review.googlesource.com/886362 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent ffa4cbb6
...@@ -71,7 +71,10 @@ ...@@ -71,7 +71,10 @@
'compiler/translator/FoldExpressions.h', 'compiler/translator/FoldExpressions.h',
'compiler/translator/HashNames.cpp', 'compiler/translator/HashNames.cpp',
'compiler/translator/HashNames.h', 'compiler/translator/HashNames.h',
'compiler/translator/ImmutableString.cpp',
'compiler/translator/ImmutableString.h', 'compiler/translator/ImmutableString.h',
'compiler/translator/ImmutableStringBuilder.cpp',
'compiler/translator/ImmutableStringBuilder.h',
'compiler/translator/InfoSink.cpp', 'compiler/translator/InfoSink.cpp',
'compiler/translator/InfoSink.h', 'compiler/translator/InfoSink.h',
'compiler/translator/Initialize.cpp', 'compiler/translator/Initialize.cpp',
......
//
// Copyright (c) 2018 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.
//
// ImmutableString.cpp: Wrapper for static or pool allocated char arrays, that are guaranteed to be
// valid and unchanged for the duration of the compilation.
//
#include "compiler/translator/ImmutableString.h"
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
{
return os.write(str.data(), str.length());
}
...@@ -45,10 +45,13 @@ class ImmutableString ...@@ -45,10 +45,13 @@ class ImmutableString
{ {
} }
constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
ImmutableString(const ImmutableString &) = default; ImmutableString(const ImmutableString &) = default;
ImmutableString &operator=(const ImmutableString &) = default; ImmutableString &operator=(const ImmutableString &) = default;
const char *data() const { return mData ? mData : ""; } const char *data() const { return mData ? mData : ""; }
size_t length() const { return mLength; }
bool operator<(const ImmutableString &b) const bool operator<(const ImmutableString &b) const
{ {
...@@ -64,10 +67,12 @@ class ImmutableString ...@@ -64,10 +67,12 @@ class ImmutableString
} }
private: private:
const char *const mData; const char *mData;
const size_t mLength; size_t mLength;
}; };
} // namespace sh } // namespace sh
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str);
#endif // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_ #endif // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
//
// Copyright (c) 2018 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.
//
// ImmutableStringBuilder.cpp: Stringstream-like utility for building pool allocated strings where
// the maximum length is known in advance.
//
#include "compiler/translator/ImmutableStringBuilder.h"
namespace sh
{
ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const ImmutableString &str)
{
ASSERT(mData != nullptr);
ASSERT(mPos + str.length() <= mMaxLength);
memcpy(mData + mPos, str.data(), str.length());
mPos += str.length();
return *this;
}
ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char *str)
{
ASSERT(mData != nullptr);
size_t len = strlen(str);
ASSERT(mPos + len <= mMaxLength);
memcpy(mData + mPos, str, len);
mPos += len;
return *this;
}
ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char &c)
{
ASSERT(mData != nullptr);
ASSERT(mPos + 1 <= mMaxLength);
mData[mPos++] = c;
return *this;
}
ImmutableStringBuilder::operator ImmutableString()
{
mData[mPos] = '\0';
ImmutableString str(static_cast<const char *>(mData), mPos);
#if defined(ANGLE_ENABLE_ASSERTS)
// Make sure that nothing is added to the string after it is finalized.
mData = nullptr;
#endif
return str;
}
} // namespace sh
//
// Copyright (c) 2018 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.
//
// ImmutableStringBuilder.h: Stringstream-like utility for building pool allocated strings where the
// maximum length is known in advance.
//
#ifndef COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
#define COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
#include "compiler/translator/ImmutableString.h"
namespace sh
{
class ImmutableStringBuilder
{
public:
ImmutableStringBuilder(size_t maxLength)
: mPos(0u), mMaxLength(maxLength), mData(AllocateEmptyPoolCharArray(maxLength))
{
}
ImmutableStringBuilder &operator<<(const ImmutableString &str);
ImmutableStringBuilder &operator<<(const char *str);
ImmutableStringBuilder &operator<<(const char &c);
// This invalidates the ImmutableStringBuilder, so it should only be called once.
operator ImmutableString();
private:
inline static char *AllocateEmptyPoolCharArray(size_t strLength)
{
size_t requiredSize = strLength + 1u;
return reinterpret_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
}
size_t mPos;
size_t mMaxLength;
char *mData;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "compiler/translator/TextureFunctionHLSL.h" #include "compiler/translator/TextureFunctionHLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/UtilsHLSL.h" #include "compiler/translator/UtilsHLSL.h"
namespace sh namespace sh
...@@ -104,8 +105,8 @@ void OutputIntTexCoordWraps(TInfoSinkBase &out, ...@@ -104,8 +105,8 @@ void OutputIntTexCoordWraps(TInfoSinkBase &out,
void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out, void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction, const TextureFunctionHLSL::TextureFunction &textureFunction,
const TString &textureReference, const ImmutableString &textureReference,
const TString &samplerReference) const ImmutableString &samplerReference)
{ {
out << textureReference; out << textureReference;
if (IsIntegerSampler(textureFunction.sampler) || if (IsIntegerSampler(textureFunction.sampler) ||
...@@ -450,37 +451,56 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out, ...@@ -450,37 +451,56 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
void GetTextureReference(TInfoSinkBase &out, void GetTextureReference(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction, const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType, const ShShaderOutput outputType,
TString *textureReference, ImmutableString *textureReference,
TString *samplerReference) ImmutableString *samplerReference)
{ {
if (outputType == SH_HLSL_4_1_OUTPUT) if (outputType == SH_HLSL_4_1_OUTPUT)
{ {
TString suffix = TextureGroupSuffix(textureFunction.sampler); static const ImmutableString kTexturesStr("textures");
static const ImmutableString kSamplersStr("samplers");
static const ImmutableString kSamplerIndexStr("[samplerIndex]");
static const ImmutableString kTextureIndexStr("[textureIndex]");
static const ImmutableString kSamplerArrayIndexStr("[samplerArrayIndex]");
ImmutableString suffix(TextureGroupSuffix(textureFunction.sampler));
if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D) if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D)
{ {
*textureReference = TString("textures") + suffix + "[samplerIndex]"; ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
*samplerReference = TString("samplers") + suffix + "[samplerIndex]"; kSamplerIndexStr.length());
textureRefBuilder << kTexturesStr << suffix << kSamplerIndexStr;
*textureReference = textureRefBuilder;
ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
kSamplerIndexStr.length());
samplerRefBuilder << kSamplersStr << suffix << kSamplerIndexStr;
*samplerReference = samplerRefBuilder;
} }
else else
{ {
out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix out << " const uint textureIndex = samplerIndex - textureIndexOffset"
<< ";\n"; << suffix.data() << ";\n";
*textureReference = TString("textures") + suffix + "[textureIndex]"; ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" << suffix kTextureIndexStr.length());
<< ";\n"; textureRefBuilder << kTexturesStr << suffix << kTextureIndexStr;
*samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]"; *textureReference = textureRefBuilder;
out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset"
<< suffix.data() << ";\n";
ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
kSamplerArrayIndexStr.length());
samplerRefBuilder << kSamplersStr << suffix << kSamplerArrayIndexStr;
*samplerReference = samplerRefBuilder;
} }
} }
else else
{ {
*textureReference = "x"; *textureReference = ImmutableString("x");
*samplerReference = "s"; *samplerReference = ImmutableString("s");
} }
} }
void OutputTextureSizeFunctionBody(TInfoSinkBase &out, void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction, const TextureFunctionHLSL::TextureFunction &textureFunction,
const TString &textureReference, const ImmutableString &textureReference,
bool getDimensionsIgnoresBaseLevel) bool getDimensionsIgnoresBaseLevel)
{ {
if (IsSampler2DMS(textureFunction.sampler)) if (IsSampler2DMS(textureFunction.sampler))
...@@ -565,7 +585,7 @@ void OutputIntegerTextureSampleFunctionComputations( ...@@ -565,7 +585,7 @@ void OutputIntegerTextureSampleFunctionComputations(
TInfoSinkBase &out, TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction, const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType, const ShShaderOutput outputType,
const TString &textureReference, const ImmutableString &textureReference,
TString *texCoordX, TString *texCoordX,
TString *texCoordY, TString *texCoordY,
TString *texCoordZ) TString *texCoordZ)
...@@ -811,8 +831,8 @@ void OutputTextureSampleFunctionReturnStatement( ...@@ -811,8 +831,8 @@ void OutputTextureSampleFunctionReturnStatement(
TInfoSinkBase &out, TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction, const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType, const ShShaderOutput outputType,
const TString &textureReference, const ImmutableString &textureReference,
const TString &samplerReference, const ImmutableString &samplerReference,
const TString &texCoordX, const TString &texCoordX,
const TString &texCoordY, const TString &texCoordY,
const TString &texCoordZ) const TString &texCoordZ)
...@@ -1291,8 +1311,8 @@ void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, ...@@ -1291,8 +1311,8 @@ void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
// sampling we need to call the function directly on references to the texture and sampler // sampling we need to call the function directly on references to the texture and sampler
// arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture* // arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture*
// tests. // tests.
TString textureReference; ImmutableString textureReference("");
TString samplerReference; ImmutableString samplerReference("");
GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference); GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference);
if (textureFunction.method == TextureFunction::SIZE) if (textureFunction.method == TextureFunction::SIZE)
......
...@@ -218,7 +218,7 @@ HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat ...@@ -218,7 +218,7 @@ HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat
return HLSL_TEXTURE_UNKNOWN; return HLSL_TEXTURE_UNKNOWN;
} }
TString TextureString(const HLSLTextureGroup textureGroup) const char *TextureString(const HLSLTextureGroup textureGroup)
{ {
switch (textureGroup) switch (textureGroup)
{ {
...@@ -277,12 +277,12 @@ TString TextureString(const HLSLTextureGroup textureGroup) ...@@ -277,12 +277,12 @@ TString TextureString(const HLSLTextureGroup textureGroup)
return "<unknown read texture type>"; return "<unknown read texture type>";
} }
TString TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) const char *TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
{ {
return TextureString(TextureGroup(type, imageInternalFormat)); return TextureString(TextureGroup(type, imageInternalFormat));
} }
TString TextureGroupSuffix(const HLSLTextureGroup type) const char *TextureGroupSuffix(const HLSLTextureGroup type)
{ {
switch (type) switch (type)
{ {
...@@ -341,7 +341,8 @@ TString TextureGroupSuffix(const HLSLTextureGroup type) ...@@ -341,7 +341,8 @@ TString TextureGroupSuffix(const HLSLTextureGroup type)
return "<unknown texture type>"; return "<unknown texture type>";
} }
TString TextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) const char *TextureGroupSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat)
{ {
return TextureGroupSuffix(TextureGroup(type, imageInternalFormat)); return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
} }
......
...@@ -87,11 +87,11 @@ enum HLSLRWTextureGroup ...@@ -87,11 +87,11 @@ enum HLSLRWTextureGroup
HLSLTextureGroup TextureGroup(const TBasicType type, HLSLTextureGroup TextureGroup(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureString(const HLSLTextureGroup textureGroup); const char *TextureString(const HLSLTextureGroup textureGroup);
TString TextureString(const TBasicType type, const char *TextureString(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureGroupSuffix(const HLSLTextureGroup type); const char *TextureGroupSuffix(const HLSLTextureGroup type);
TString TextureGroupSuffix(const TBasicType type, const char *TextureGroupSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureTypeSuffix(const TBasicType type, TString TextureTypeSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
......
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