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 @@
'compiler/translator/FoldExpressions.h',
'compiler/translator/HashNames.cpp',
'compiler/translator/HashNames.h',
'compiler/translator/ImmutableString.cpp',
'compiler/translator/ImmutableString.h',
'compiler/translator/ImmutableStringBuilder.cpp',
'compiler/translator/ImmutableStringBuilder.h',
'compiler/translator/InfoSink.cpp',
'compiler/translator/InfoSink.h',
'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
{
}
constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
ImmutableString(const ImmutableString &) = default;
ImmutableString &operator=(const ImmutableString &) = default;
const char *data() const { return mData ? mData : ""; }
size_t length() const { return mLength; }
bool operator<(const ImmutableString &b) const
{
......@@ -64,10 +67,12 @@ class ImmutableString
}
private:
const char *const mData;
const size_t mLength;
const char *mData;
size_t mLength;
};
} // namespace sh
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str);
#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 @@
#include "compiler/translator/TextureFunctionHLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/UtilsHLSL.h"
namespace sh
......@@ -104,8 +105,8 @@ void OutputIntTexCoordWraps(TInfoSinkBase &out,
void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
const TString &textureReference,
const TString &samplerReference)
const ImmutableString &textureReference,
const ImmutableString &samplerReference)
{
out << textureReference;
if (IsIntegerSampler(textureFunction.sampler) ||
......@@ -450,37 +451,56 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
void GetTextureReference(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType,
TString *textureReference,
TString *samplerReference)
ImmutableString *textureReference,
ImmutableString *samplerReference)
{
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)
{
*textureReference = TString("textures") + suffix + "[samplerIndex]";
*samplerReference = TString("samplers") + suffix + "[samplerIndex]";
ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
kSamplerIndexStr.length());
textureRefBuilder << kTexturesStr << suffix << kSamplerIndexStr;
*textureReference = textureRefBuilder;
ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
kSamplerIndexStr.length());
samplerRefBuilder << kSamplersStr << suffix << kSamplerIndexStr;
*samplerReference = samplerRefBuilder;
}
else
{
out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix
<< ";\n";
*textureReference = TString("textures") + suffix + "[textureIndex]";
out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" << suffix
<< ";\n";
*samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]";
out << " const uint textureIndex = samplerIndex - textureIndexOffset"
<< suffix.data() << ";\n";
ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
kTextureIndexStr.length());
textureRefBuilder << kTexturesStr << suffix << kTextureIndexStr;
*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
{
*textureReference = "x";
*samplerReference = "s";
*textureReference = ImmutableString("x");
*samplerReference = ImmutableString("s");
}
}
void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
const TString &textureReference,
const ImmutableString &textureReference,
bool getDimensionsIgnoresBaseLevel)
{
if (IsSampler2DMS(textureFunction.sampler))
......@@ -565,7 +585,7 @@ void OutputIntegerTextureSampleFunctionComputations(
TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType,
const TString &textureReference,
const ImmutableString &textureReference,
TString *texCoordX,
TString *texCoordY,
TString *texCoordZ)
......@@ -811,8 +831,8 @@ void OutputTextureSampleFunctionReturnStatement(
TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
const ShShaderOutput outputType,
const TString &textureReference,
const TString &samplerReference,
const ImmutableString &textureReference,
const ImmutableString &samplerReference,
const TString &texCoordX,
const TString &texCoordY,
const TString &texCoordZ)
......@@ -1291,8 +1311,8 @@ void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
// 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*
// tests.
TString textureReference;
TString samplerReference;
ImmutableString textureReference("");
ImmutableString samplerReference("");
GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference);
if (textureFunction.method == TextureFunction::SIZE)
......
......@@ -218,7 +218,7 @@ HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat
return HLSL_TEXTURE_UNKNOWN;
}
TString TextureString(const HLSLTextureGroup textureGroup)
const char *TextureString(const HLSLTextureGroup textureGroup)
{
switch (textureGroup)
{
......@@ -277,12 +277,12 @@ TString TextureString(const HLSLTextureGroup textureGroup)
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));
}
TString TextureGroupSuffix(const HLSLTextureGroup type)
const char *TextureGroupSuffix(const HLSLTextureGroup type)
{
switch (type)
{
......@@ -341,7 +341,8 @@ TString TextureGroupSuffix(const HLSLTextureGroup 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));
}
......
......@@ -87,12 +87,12 @@ enum HLSLRWTextureGroup
HLSLTextureGroup TextureGroup(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureString(const HLSLTextureGroup textureGroup);
TString TextureString(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureGroupSuffix(const HLSLTextureGroup type);
TString TextureGroupSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
const char *TextureString(const HLSLTextureGroup textureGroup);
const char *TextureString(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
const char *TextureGroupSuffix(const HLSLTextureGroup type);
const char *TextureGroupSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
TString TextureTypeSuffix(const TBasicType type,
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
......
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