summaryrefslogtreecommitdiff
path: root/sokol_gfx.h
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2019-09-06 15:56:40 +0200
committerAndre Weissflog <floooh@gmail.com>2019-09-06 15:56:40 +0200
commit68f84820844e5bcfbd5e65bc34bd77e64ac8879a (patch)
tree73040d1185bcae1f0f7f1eda43153be9fc0adaf9 /sokol_gfx.h
parentd3657474d99f17204763f7ee3b94582812d55536 (diff)
sokol_gfx.h Metal: initial border color support for macOS
Diffstat (limited to 'sokol_gfx.h')
-rw-r--r--sokol_gfx.h94
1 files changed, 78 insertions, 16 deletions
diff --git a/sokol_gfx.h b/sokol_gfx.h
index c8e00ce5..7a26af94 100644
--- a/sokol_gfx.h
+++ b/sokol_gfx.h
@@ -739,7 +739,7 @@ typedef struct sg_features {
bool msaa_render_targets:1;
bool imagetype_3d:1; /* creation of SG_IMAGETYPE_3D images is supported */
bool imagetype_array:1; /* creation of SG_IMAGETYPE_ARRAY images is supported */
- bool image_border_color:1;
+ bool clamp_to_border:1; /* border color and clamp-to-border UV-wrap mode is supported */
} sg_features;
/*
@@ -960,6 +960,14 @@ typedef enum sg_filter {
and .wrap_w members when creating an image.
The default wrap mode is SG_WRAP_REPEAT.
+
+ NOTE: SG_WRAP_CLAMP_TO_BORDER is not supported on all backends
+ and platforms. To check for support, call sg_query_features()
+ and check the "clamp_to_border" boolean in the returned
+ sg_features struct.
+
+ Platforms which don't support SG_WRAP_CLAMP_TO_BORDER will silently fall back
+ to SG_WRAP_CLAMP_TO_EDGE without a validation error.
*/
typedef enum sg_wrap {
_SG_WRAP_DEFAULT, /* value 0 reserved for default-init */
@@ -972,6 +980,23 @@ typedef enum sg_wrap {
} sg_wrap;
/*
+ sg_border_color
+
+ The border color to use when sampling a texture, and the UV wrap
+ mode is SG_WRAP_CLAMP_TO_BORDER.
+
+ The default border color is SG_BORDERCOLOR_OPAQUE_BLACK
+*/
+typedef enum sg_border_color {
+ _SG_BORDERCOLOR_DEFAULT, /* value 0 reserved for default-init */
+ SG_BORDERCOLOR_TRANSPARENT_BLACK,
+ SG_BORDERCOLOR_OPAQUE_BLACK,
+ SG_BORDERCOLOR_OPAQUE_WHITE,
+ _SG_BORDERCOLOR_NUM,
+ _SG_BORDERCOLOR_FORCE_U32 = 0x7FFFFFFF
+} sg_border_color;
+
+/*
sg_vertex_format
The data type of a vertex component. This is used to describe
@@ -1424,6 +1449,7 @@ typedef struct sg_image_content {
.wrap_u: SG_WRAP_REPEAT
.wrap_v: SG_WRAP_REPEAT
.wrap_w: SG_WRAP_REPEAT (only SG_IMAGETYPE_3D)
+ .border_color SG_BORDERCOLOR_OPAQUE_BLACK
.max_anisotropy 1 (must be 1..16)
.min_lod 0.0f
.max_lod FLT_MAX
@@ -1470,8 +1496,8 @@ typedef struct sg_image_desc {
sg_wrap wrap_u;
sg_wrap wrap_v;
sg_wrap wrap_w;
+ sg_border_color border_color;
uint32_t max_anisotropy;
- float border_color[4];
float min_lod;
float max_lod;
sg_image_content content;
@@ -2611,7 +2637,7 @@ typedef struct {
sg_wrap wrap_u;
sg_wrap wrap_v;
sg_wrap wrap_w;
- float border_color[4];
+ sg_border_color border_color;
uint32_t max_anisotropy;
uint32_t upd_frame_index;
DXGI_FORMAT d3d11_format;
@@ -2765,6 +2791,7 @@ typedef struct {
sg_wrap wrap_u;
sg_wrap wrap_v;
sg_wrap wrap_w;
+ sg_border_color border_color;
uint32_t max_anisotropy;
int min_lod; /* orig min/max_lod is float, this is int(min/max_lod*1000.0) */
int max_lod;
@@ -4519,7 +4546,7 @@ _SOKOL_PRIVATE void _sg_gl_init_caps_glcore33(void) {
_sg.features.msaa_render_targets = true;
_sg.features.imagetype_3d = true;
_sg.features.imagetype_array = true;
- _sg.features.image_border_color = false;
+ _sg.features.clamp_to_border = false;
/* scan extensions */
bool has_s3tc = false; /* BC1..BC3 */
@@ -4594,7 +4621,7 @@ _SOKOL_PRIVATE void _sg_gl_init_caps_gles3(void) {
_sg.features.msaa_render_targets = true;
_sg.features.imagetype_3d = true;
_sg.features.imagetype_array = true;
- _sg.features.image_border_color = false;
+ _sg.features.clamp_to_border = false;
bool has_s3tc = false; /* BC1..BC3 */
bool has_rgtc = false; /* BC4 and BC5 */
@@ -4719,7 +4746,7 @@ _SOKOL_PRIVATE void _sg_gl_init_caps_gles2(void) {
_sg.features.msaa_render_targets = false;
_sg.features.imagetype_3d = false;
_sg.features.imagetype_array = false;
- _sg.features.image_border_color = false;
+ _sg.features.clamp_to_border = false;
/* limits */
_sg_gl_init_limits();
@@ -6533,7 +6560,7 @@ _SOKOL_PRIVATE void _sg_d3d11_init_caps(void) {
_sg.features.msaa_render_targets = true;
_sg.features.imagetype_3d = true;
_sg.features.imagetype_array = true;
- _sg.features.image_border_color = true;
+ _sg.features.clamp_to_border = true;
_sg.limits.max_image_size_2d = 16 * 1024;
_sg.limits.max_image_size_cube = 16 * 1024;
@@ -6716,10 +6743,7 @@ _SOKOL_PRIVATE sg_resource_state _sg_create_image(_sg_image_t* img, const sg_ima
img->wrap_u = desc->wrap_u;
img->wrap_v = desc->wrap_v;
img->wrap_w = desc->wrap_w;
- img->border_color[0] = desc->border_color[0];
- img->border_color[1] = desc->border_color[1];
- img->border_color[2] = desc->border_color[2];
- img->border_color[3] = desc->border_color[3];
+ img->border_color = desc->border_color;
img->max_anisotropy = desc->max_anisotropy;
img->upd_frame_index = 0;
const bool injected = (0 != desc->d3d11_texture);
@@ -6900,10 +6924,20 @@ _SOKOL_PRIVATE sg_resource_state _sg_create_image(_sg_image_t* img, const sg_ima
d3d11_smp_desc.AddressU = _sg_d3d11_address_mode(img->wrap_u);
d3d11_smp_desc.AddressV = _sg_d3d11_address_mode(img->wrap_v);
d3d11_smp_desc.AddressW = _sg_d3d11_address_mode(img->wrap_w);
- d3d11_smp_desc.BorderColor[0] = img->border_color[0];
- d3d11_smp_desc.BorderColor[1] = img->border_color[1];
- d3d11_smp_desc.BorderColor[2] = img->border_color[2];
- d3d11_smp_desc.BorderColor[3] = img->border_color[3];
+ switch (img->border_color) {
+ case SG_BORDERCOLOR_TRANSPARENT_BLACK:
+ /* all 0.0f */
+ break;
+ case SG_BORDERCOLOR_OPAQUE_WHITE:
+ for (int i = 0; i < 4; i++) {
+ d3d11_smp_desc.BorderColor[i] = 1.0f;
+ break;
+ break;
+ default:
+ /* opaque black */
+ d3d11_smp_desc.BorderColor[3] = 1.0f;
+ break;
+ }
d3d11_smp_desc.MaxAnisotropy = img->max_anisotropy;
d3d11_smp_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
d3d11_smp_desc.MinLOD = desc->min_lod;
@@ -7946,11 +7980,28 @@ _SOKOL_PRIVATE MTLSamplerAddressMode _sg_mtl_address_mode(sg_wrap w) {
switch (w) {
case SG_WRAP_REPEAT: return MTLSamplerAddressModeRepeat;
case SG_WRAP_CLAMP_TO_EDGE: return MTLSamplerAddressModeClampToEdge;
+ #if defined(_SG_TARGET_MACOS)
+ case SG_WRAP_CLAMP_TO_BORDER: return MTLSamplerAddressModeClampToBorderColor;
+ #else
+ /* clamp-to-border not supported on iOS, fall back to clamp-to-edge */
+ case SG_WRAP_CLAMP_TO_BORDER: return MTLSamplerAddressModeClampToEdge;
+ #endif
case SG_WRAP_MIRRORED_REPEAT: return MTLSamplerAddressModeMirrorRepeat;
default: SOKOL_UNREACHABLE; return (MTLSamplerAddressMode)0;
}
}
+#if defined(_SG_TARGET_MACOS)
+_SOKOL_PRIVATE MTLSamplerBorderColor _sg_mtl_border_color(sg_border_color c) {
+ switch (c) {
+ case SG_BORDERCOLOR_TRANSPARENT_BLACK: return MTLSamplerBorderColorTransparentBlack;
+ case SG_BORDERCOLOR_OPAQUE_BLACK: return MTLSamplerBorderColorOpaqueBlack;
+ case SG_BORDERCOLOR_OPAQUE_WHITE: return MTLSamplerBorderColorOpaqueWhite;
+ default: SOKOL_UNREACHABLE; return (MTLSamplerBorderColor)0;
+ }
+}
+#endif
+
_SOKOL_PRIVATE MTLSamplerMinMagFilter _sg_mtl_minmag_filter(sg_filter f) {
switch (f) {
case SG_FILTER_NEAREST:
@@ -8141,6 +8192,7 @@ _SOKOL_PRIVATE uint32_t _sg_mtl_create_sampler(id<MTLDevice> mtl_device, const s
const sg_wrap wrap_u = img_desc->wrap_u;
const sg_wrap wrap_v = img_desc->wrap_v;
const sg_wrap wrap_w = img_desc->wrap_w;
+ const sg_border_color border_color = img_desc->border_color;
const uint32_t max_anisotropy = img_desc->max_anisotropy;
/* convert floats to valid int for proper comparison */
const int min_lod = (int)(img_desc->min_lod * 1000.0f);
@@ -8154,6 +8206,7 @@ _SOKOL_PRIVATE uint32_t _sg_mtl_create_sampler(id<MTLDevice> mtl_device, const s
(wrap_v == item->wrap_v) &&
(wrap_w == item->wrap_w) &&
(max_anisotropy == item->max_anisotropy) &&
+ (border_color == item->border_color) &&
(min_lod == item->min_lod) &&
(max_lod == item->max_lod))
{
@@ -8171,12 +8224,16 @@ _SOKOL_PRIVATE uint32_t _sg_mtl_create_sampler(id<MTLDevice> mtl_device, const s
new_item->min_lod = min_lod;
new_item->max_lod = max_lod;
new_item->max_anisotropy = max_anisotropy;
+ new_item->border_color = border_color;
MTLSamplerDescriptor* mtl_desc = [[MTLSamplerDescriptor alloc] init];
mtl_desc.sAddressMode = _sg_mtl_address_mode(wrap_u);
mtl_desc.tAddressMode = _sg_mtl_address_mode(wrap_v);
if (SG_IMAGETYPE_3D == img_desc->type) {
mtl_desc.rAddressMode = _sg_mtl_address_mode(wrap_w);
}
+ #if defined(_SG_TARGET_MACOS)
+ mtl_desc.borderColor = _sg_mtl_border_color(border_color);
+ #endif
mtl_desc.minFilter = _sg_mtl_minmag_filter(min_filter);
mtl_desc.magFilter = _sg_mtl_minmag_filter(mag_filter);
mtl_desc.mipFilter = _sg_mtl_mip_filter(min_filter);
@@ -8210,7 +8267,11 @@ _SOKOL_PRIVATE void _sg_mtl_init_caps(void) {
_sg.features.msaa_render_targets = true;
_sg.features.imagetype_3d = true;
_sg.features.imagetype_array = true;
- _sg.features.image_border_color = false;
+ #if defined(_SG_TARGET_MACOS)
+ _sg.features.clamp_to_border = true;
+ #else
+ _sg.features.clamp_to_border = false;
+ #endif
#if defined(_SG_TARGET_MACOS)
_sg.limits.max_image_size_2d = 16 * 1024;
@@ -10411,6 +10472,7 @@ _SOKOL_PRIVATE sg_image_desc _sg_image_desc_defaults(const sg_image_desc* desc)
def.wrap_u = _sg_def(def.wrap_u, SG_WRAP_REPEAT);
def.wrap_v = _sg_def(def.wrap_v, SG_WRAP_REPEAT);
def.wrap_w = _sg_def(def.wrap_w, SG_WRAP_REPEAT);
+ def.border_color = _sg_def(def.border_color, SG_BORDERCOLOR_OPAQUE_BLACK);
def.max_anisotropy = _sg_def(def.max_anisotropy, 1);
def.max_lod = _sg_def_flt(def.max_lod, FLT_MAX);
return def;