Skip to content

Commit f23a152

Browse files
lhkbobSkia Commit-Bot
authored andcommitted
Reland "Add clamp to border wrap mode to gpu"
This reverts commit 8137f3c. Reason for revert: update GrCaps clampToBorder for iOS and Mac 10.11 Original change's description: > Revert "Add clamp to border wrap mode to gpu" > > This reverts commit f49a578. > > Reason for revert: clamp-to-border in metal not available on iOS > > Original change's description: > > Add clamp to border wrap mode to gpu > > > > Bug: skia: > > Change-Id: I286163cdea4fa8f7e6a876baaa11aa3dacd4f2ff > > Reviewed-on: https://skia-review.googlesource.com/c/175244 > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Reviewed-by: Greg Daniel <egdaniel@google.com> > > Commit-Queue: Michael Ludwig <michaelludwig@google.com> > > TBR=egdaniel@google.com,bsalomon@google.com,ethannicholas@google.com,michaelludwig@google.com > > Change-Id: I01ef28d9c2fbf6c6dcd82d9aac193ff102d60151 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia: > Reviewed-on: https://skia-review.googlesource.com/c/175988 > Reviewed-by: Michael Ludwig <michaelludwig@google.com> > Commit-Queue: Michael Ludwig <michaelludwig@google.com> TBR=egdaniel@google.com,bsalomon@google.com,ethannicholas@google.com,michaelludwig@google.com Change-Id: I37467eb096fec28131587aefe340f0485fca59d4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia: Reviewed-on: https://skia-review.googlesource.com/c/175989 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
1 parent be5a093 commit f23a152

File tree

11 files changed

+100
-16
lines changed

11 files changed

+100
-16
lines changed

include/gpu/GrSamplerState.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
class GrSamplerState {
1717
public:
1818
enum class Filter : uint8_t { kNearest, kBilerp, kMipMap };
19-
enum class WrapMode : uint8_t { kClamp, kRepeat, kMirrorRepeat };
19+
enum class WrapMode : uint8_t { kClamp, kRepeat, kMirrorRepeat, kClampToBorder };
2020

2121
static constexpr GrSamplerState ClampNearest() { return GrSamplerState(); }
2222
static constexpr GrSamplerState ClampBilerp() {
@@ -51,7 +51,8 @@ class GrSamplerState {
5151
WrapMode wrapModeY() const { return fWrapModes[1]; }
5252

5353
bool isRepeated() const {
54-
return WrapMode::kClamp != fWrapModes[0] || WrapMode::kClamp != fWrapModes[1];
54+
return (WrapMode::kClamp != fWrapModes[0] && WrapMode::kClampToBorder != fWrapModes[0]) ||
55+
(WrapMode::kClamp != fWrapModes[1] && WrapMode::kClampToBorder != fWrapModes[1]);
5556
}
5657

5758
bool operator==(const GrSamplerState& that) const {

src/gpu/GrCaps.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ GrCaps::GrCaps(const GrContextOptions& options) {
7272

7373
fPreferVRAMUseOverFlushes = true;
7474

75+
// Default to true, allow older versions of OpenGL to disable explicitly
76+
fClampToBorderSupport = true;
77+
7578
fDriverBugWorkarounds = options.fDriverBugWorkarounds;
7679
}
7780

src/gpu/GrCaps.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ class GrCaps : public SkRefCnt {
311311
*/
312312
GrBackendFormat createFormatFromBackendTexture(const GrBackendTexture&) const;
313313

314+
/**
315+
* The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and
316+
* GLES 3.2, but is also available in extensions. Vulkan and Metal always have support.
317+
*/
318+
bool clampToBorderSupport() const { return fClampToBorderSupport; }
319+
314320
const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
315321

316322
protected:
@@ -347,6 +353,7 @@ class GrCaps : public SkRefCnt {
347353
bool fMustClearUploadedBufferData : 1;
348354
bool fSupportsAHardwareBufferImages : 1;
349355
bool fHalfFloatVertexAttributeSupport : 1;
356+
bool fClampToBorderSupport : 1;
350357

351358
// Driver workaround
352359
bool fBlacklistCoverageCounting : 1;

src/gpu/gl/GrGLCaps.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,21 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
235235
// lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
236236
}
237237

238+
// GrCaps defaults fClampToBorderSupport to true, so disable when unsupported
239+
if (kGL_GrGLStandard == standard) {
240+
// Clamp to border added in 1.3
241+
if (version < GR_GL_VER(1, 3) && !ctxInfo.hasExtension("GL_ARB_texture_border_clamp")) {
242+
fClampToBorderSupport = false;
243+
}
244+
} else if (kGLES_GrGLStandard == standard) {
245+
// GLES didn't have clamp to border until 3.2, but provides several alternative extensions
246+
if (version < GR_GL_VER(3, 2) && !ctxInfo.hasExtension("GL_EXT_texture_border_clamp") &&
247+
!ctxInfo.hasExtension("GL_NV_texture_border_clamp") &&
248+
!ctxInfo.hasExtension("GL_OES_texture_border_clamp")) {
249+
fClampToBorderSupport = false;
250+
}
251+
}
252+
238253
if (kGL_GrGLStandard == standard) {
239254
if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
240255
fTextureSwizzleSupport = true;

src/gpu/gl/GrGLDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@
670670
#define GR_GL_REPEAT 0x2901
671671
#define GR_GL_CLAMP_TO_EDGE 0x812F
672672
#define GR_GL_MIRRORED_REPEAT 0x8370
673+
#define GR_GL_CLAMP_TO_BORDER 0x812D
673674

674675
/* Texture Swizzle */
675676
#define GR_GL_TEXTURE_SWIZZLE_R 0x8E42

src/gpu/gl/GrGLGpu.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,16 @@ static GrGLenum filter_to_gl_min_filter(GrSamplerState::Filter filter) {
202202
return 0;
203203
}
204204

205-
static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode) {
205+
static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode,
206+
const GrCaps& caps) {
206207
switch (wrapMode) {
207208
case GrSamplerState::WrapMode::kClamp: return GR_GL_CLAMP_TO_EDGE;
208209
case GrSamplerState::WrapMode::kRepeat: return GR_GL_REPEAT;
209210
case GrSamplerState::WrapMode::kMirrorRepeat: return GR_GL_MIRRORED_REPEAT;
211+
case GrSamplerState::WrapMode::kClampToBorder:
212+
// May not be supported but should have been caught earlier
213+
SkASSERT(caps.clampToBorderSupport());
214+
return GR_GL_CLAMP_TO_BORDER;
210215
}
211216
SK_ABORT("Unknown wrap mode");
212217
return 0;
@@ -242,8 +247,8 @@ class GrGLGpu::SamplerObjectCache {
242247
fSamplers[index] = s;
243248
auto minFilter = filter_to_gl_min_filter(state.filter());
244249
auto magFilter = filter_to_gl_mag_filter(state.filter());
245-
auto wrapX = wrap_mode_to_gl_wrap(state.wrapModeX());
246-
auto wrapY = wrap_mode_to_gl_wrap(state.wrapModeY());
250+
auto wrapX = wrap_mode_to_gl_wrap(state.wrapModeX(), fGpu->glCaps());
251+
auto wrapY = wrap_mode_to_gl_wrap(state.wrapModeY(), fGpu->glCaps());
247252
GR_GL_CALL(fGpu->glInterface(),
248253
SamplerParameteri(s, GR_GL_TEXTURE_MIN_FILTER, minFilter));
249254
GR_GL_CALL(fGpu->glInterface(),
@@ -284,16 +289,16 @@ class GrGLGpu::SamplerObjectCache {
284289
int filter = static_cast<int>(state.filter());
285290
SkASSERT(filter >= 0 && filter < 3);
286291
int wrapX = static_cast<int>(state.wrapModeX());
287-
SkASSERT(wrapX >= 0 && wrapX < 3);
292+
SkASSERT(wrapX >= 0 && wrapX < 4);
288293
int wrapY = static_cast<int>(state.wrapModeY());
289-
SkASSERT(wrapY >= 0 && wrapY < 3);
290-
int idx = 9 * filter + 3 * wrapX + wrapY;
294+
SkASSERT(wrapY >= 0 && wrapY < 4);
295+
int idx = 16 * filter + 4 * wrapX + wrapY;
291296
SkASSERT(idx < kNumSamplers);
292297
return idx;
293298
}
294299

295300
GrGLGpu* fGpu;
296-
static constexpr int kNumSamplers = 27;
301+
static constexpr int kNumSamplers = 48;
297302
std::unique_ptr<GrGLuint[]> fHWBoundSamplers;
298303
GrGLuint fSamplers[kNumSamplers];
299304
int fNumTextureUnits;
@@ -2854,8 +2859,8 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
28542859
newSamplerParams.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
28552860
newSamplerParams.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
28562861

2857-
newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX());
2858-
newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY());
2862+
newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
2863+
newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
28592864

28602865
// These are the OpenGL default values.
28612866
newSamplerParams.fMinLOD = -1000;
@@ -2889,6 +2894,17 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
28892894
this->setTextureUnit(unitIdx);
28902895
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerParams.fWrapT));
28912896
}
2897+
if (this->glCaps().clampToBorderSupport()) {
2898+
// Make sure the border color is transparent black (the default)
2899+
if (setAll || oldSamplerParams.fBorderColorInvalid) {
2900+
this->setTextureUnit(unitIdx);
2901+
// Specify the transparent black as normalized signed integers. The conversion is
2902+
// defined as (2c+1)/(2^32-1), which makes it impossible to map a signed in to
2903+
// exactly 0.f. But 1/(2^32-1) is close enough.
2904+
static const GrGLint kTransparentBlack[4] = {0, 0, 0, 0};
2905+
GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_BORDER_COLOR, kTransparentBlack));
2906+
}
2907+
}
28922908
}
28932909
GrGLTexture::NonSamplerParams newNonSamplerParams;
28942910
newNonSamplerParams.fBaseMipMapLevel = 0;

src/gpu/gl/GrGLTexture.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@ class GrGLTexture : public GrTexture {
2727
GrGLenum fWrapT = GR_GL_REPEAT;
2828
GrGLfloat fMinLOD = -1000.f;
2929
GrGLfloat fMaxLOD = 1000.f;
30+
// We always want the border color to be transparent black, so no need to store 4 floats.
31+
// Just track if it's been invalidated and no longer the default
32+
bool fBorderColorInvalid = false;
33+
3034
void invalidate() {
3135
fMinFilter = ~0U;
3236
fMagFilter = ~0U;
3337
fWrapS = ~0U;
3438
fWrapT = ~0U;
3539
fMinLOD = SK_ScalarNaN;
3640
fMaxLOD = SK_ScalarNaN;
41+
fBorderColorInvalid = true;
3742
}
3843
};
3944

src/gpu/mtl/GrMtlCaps.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,16 @@
221221
}
222222
}
223223

224+
// Clamp to border is supported on Mac 10.12 and higher (gpu family.version >= 1.2). It is not
225+
// supported on iOS.
226+
if (this->isMac()) {
227+
if (fFamilyGroup == 1 && fVersion < 2) {
228+
fClampToBorderSupport = false;
229+
}
230+
} else {
231+
fClampToBorderSupport = false;
232+
}
233+
224234
// Starting with the assumption that there isn't a reason to not map small buffers.
225235
fBufferMapThreshold = 0;
226236

src/gpu/mtl/GrMtlSampler.mm

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,24 @@
1010
#include "GrMtlGpu.h"
1111

1212
static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
13-
GrSamplerState::WrapMode wrapMode) {
13+
GrSamplerState::WrapMode wrapMode, const GrCaps& caps) {
1414
switch (wrapMode) {
1515
case GrSamplerState::WrapMode::kClamp:
1616
return MTLSamplerAddressModeClampToEdge;
1717
case GrSamplerState::WrapMode::kRepeat:
1818
return MTLSamplerAddressModeRepeat;
1919
case GrSamplerState::WrapMode::kMirrorRepeat:
2020
return MTLSamplerAddressModeMirrorRepeat;
21+
case GrSamplerState::WrapMode::kClampToBorder:
22+
// Must guard the reference to the clamp to border address mode by macro since iOS
23+
// builds will fail if it's referenced, even if other code makes sure it's never used.
24+
#ifdef SK_BUILD_FOR_IOS
25+
SkASSERT(false);
26+
return MTLSamplerAddressModeClampToEdge;
27+
#else
28+
SkASSERT(caps.clampToBorderSupport());
29+
return MTLSamplerAddressModeClampToBorderColor;
30+
#endif
2131
}
2232
SK_ABORT("Unknown wrap mode.");
2333
return MTLSamplerAddressModeClampToEdge;
@@ -37,8 +47,10 @@ static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
3747

3848
auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
3949
samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
40-
samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX());
41-
samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY());
50+
samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(),
51+
gpu->mtlCaps());
52+
samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(),
53+
gpu->mtlCaps());
4254
samplerDesc.magFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
4355
samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
4456
samplerDesc.mipFilter = MTLSamplerMipFilterLinear;

src/gpu/vk/GrVkSampler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
1919
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
2020
case GrSamplerState::WrapMode::kMirrorRepeat:
2121
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
22+
case GrSamplerState::WrapMode::kClampToBorder:
23+
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
2224
}
2325
SK_ABORT("Unknown wrap mode.");
2426
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;

0 commit comments

Comments
 (0)