early-access version 2281

This commit is contained in:
pineappleEA
2021-12-07 02:20:09 +01:00
parent c2ae6d480a
commit c4fa174d53
591 changed files with 36978 additions and 18653 deletions

View File

@@ -279,26 +279,35 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache,
switch (cache->vertexFunction) {
case SDL_METAL_VERTEX_SOLID:
/* position (float2) */
vertdesc.layouts[0].stride = sizeof(float) * 2;
/* position (float2), color (uchar4normalized) */
vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int);
vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
vertdesc.attributes[0].format = MTLVertexFormatFloat2;
vertdesc.attributes[0].offset = 0;
vertdesc.attributes[0].bufferIndex = 0;
vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
vertdesc.attributes[1].offset = sizeof (float) * 2;
vertdesc.attributes[1].bufferIndex = 0;
break;
case SDL_METAL_VERTEX_COPY:
/* position (float2), texcoord (float2) */
vertdesc.layouts[0].stride = sizeof(float) * 4;
/* position (float2), color (uchar4normalized), texcoord (float2) */
vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int) + sizeof (float) * 2;
vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
vertdesc.attributes[0].format = MTLVertexFormatFloat2;
vertdesc.attributes[0].offset = 0;
vertdesc.attributes[0].bufferIndex = 0;
vertdesc.attributes[1].format = MTLVertexFormatFloat2;
vertdesc.attributes[1].offset = sizeof(float) * 2;
vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
vertdesc.attributes[1].offset = sizeof (float) * 2;
vertdesc.attributes[1].bufferIndex = 0;
vertdesc.attributes[2].format = MTLVertexFormatFloat2;
vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof (int);
vertdesc.attributes[2].bufferIndex = 0;
break;
}
@@ -450,7 +459,7 @@ ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SD
return MakePipelineState(data, cache, [NSString stringWithFormat:@" (blend=custom 0x%x)", blendmode], blendmode);
}
static void
static SDL_bool
METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, MTLClearColor *clear_color, id<MTLBuffer> vertex_buffer)
{
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
@@ -472,10 +481,16 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load,
load = MTLLoadActionDontCare;
}
}
mtltexture = data.mtlbackbuffer.texture;
if (data.mtlbackbuffer != nil) {
mtltexture = data.mtlbackbuffer.texture;
}
}
SDL_assert(mtltexture);
/* mtltexture can be nil here if macOS refused to give us a drawable,
which apparently can happen for minimized windows, etc. */
if (mtltexture == nil) {
return SDL_FALSE;
}
if (load == MTLLoadActionClear) {
SDL_assert(clear_color != NULL);
@@ -508,6 +523,8 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load,
// or whatever. This means we can _always_ batch rendering commands!
[data.mtlcmdbuffer enqueue];
}
return SDL_TRUE;
}
static void
@@ -1020,13 +1037,6 @@ METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
}}
// normalize a value from 0.0f to len into 0.0f to 1.0f.
static inline float
normtex(const float _val, const float len)
{
return _val / len;
}
static int
METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
{
@@ -1060,38 +1070,56 @@ METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
if (!verts) {
return -1;
}
/*
* FIXME: not needed anymore, some cleanup to do
*
*(verts++) = ((float)cmd->data.color.r) / 255.0f;
*(verts++) = ((float)cmd->data.color.g) / 255.0f;
*(verts++) = ((float)cmd->data.color.b) / 255.0f;
*(verts++) = ((float)cmd->data.color.a) / 255.0f;
*/
return 0;
}
static int
METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
const size_t vertlen = (sizeof (float) * 2) * count;
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
SDL_memcpy(verts, points, vertlen);
for (int i = 0; i < count; i++, points++) {
*(verts++) = points->x;
*(verts++) = points->y;
*((int *)verts++) = color;
}
return 0;
}
static int
METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
SDL_assert(count >= 2); /* should have been checked at the higher level. */
const size_t vertlen = (sizeof (float) * 2) * count;
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
SDL_memcpy(verts, points, vertlen);
for (int i = 0; i < count; i++, points++) {
*(verts++) = points->x;
*(verts++) = points->y;
*((int *)verts++) = color;
}
/* If the line segment is completely horizontal or vertical,
make it one pixel longer, to satisfy the diamond-exit rule.
@@ -1101,8 +1129,8 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
that are missing a pixel that frames something and not arbitrary
angles. Maybe !!! FIXME for later, though. */
points += count - 2; /* update the last line. */
verts += (count * 2) - 2;
points -= 2; /* update the last line. */
verts -= 2 + 1;
const float xstart = points[0].x;
const float ystart = points[0].y;
@@ -1119,161 +1147,51 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
}
static int
METAL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
float scale_x, float scale_y)
{
const size_t vertlen = (sizeof (float) * 8) * count;
int count = indices ? num_indices : num_vertices;
const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count;
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
size_indices = indices ? size_indices : 0;
/* Quads in the following vertex order (matches the quad index buffer):
* 1---3
* | \ |
* 0---2
*/
for (int i = 0; i < count; i++, rects++) {
if ((rects->w <= 0.0f) || (rects->h <= 0.0f)) {
cmd->data.draw.count--;
for (int i = 0; i < count; i++) {
int j;
if (size_indices == 4) {
j = ((const Uint32 *)indices)[i];
} else if (size_indices == 2) {
j = ((const Uint16 *)indices)[i];
} else if (size_indices == 1) {
j = ((const Uint8 *)indices)[i];
} else {
*(verts++) = rects->x;
*(verts++) = rects->y + rects->h;
*(verts++) = rects->x;
*(verts++) = rects->y;
*(verts++) = rects->x + rects->w;
*(verts++) = rects->y + rects->h;
*(verts++) = rects->x + rects->w;
*(verts++) = rects->y;
j = i;
}
float *xy_ = (float *)((char*)xy + j * xy_stride);
int col_ = *(int *)((char*)color + j * color_stride);
*(verts++) = xy_[0] * scale_x;
*(verts++) = xy_[1] * scale_y;
*((int *)verts++) = col_;
if (texture) {
float *uv_ = (float *)((char*)uv + j * uv_stride);
*(verts++) = uv_[0];
*(verts++) = uv_[1];
}
}
if (cmd->data.draw.count == 0) {
cmd->command = SDL_RENDERCMD_NO_OP; // nothing to do, just skip this one later.
}
return 0;
}
static int
METAL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
{
const float texw = (float) texture->w;
const float texh = (float) texture->h;
// !!! FIXME: use an index buffer
const size_t vertlen = (sizeof (float) * 16);
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = 1;
/* Interleaved positions and texture coordinates */
*(verts++) = dstrect->x;
*(verts++) = dstrect->y + dstrect->h;
*(verts++) = normtex(srcrect->x, texw);
*(verts++) = normtex(srcrect->y + srcrect->h, texh);
*(verts++) = dstrect->x;
*(verts++) = dstrect->y;
*(verts++) = normtex(srcrect->x, texw);
*(verts++) = normtex(srcrect->y, texh);
*(verts++) = dstrect->x + dstrect->w;
*(verts++) = dstrect->y + dstrect->h;
*(verts++) = normtex(srcrect->x + srcrect->w, texw);
*(verts++) = normtex(srcrect->y + srcrect->h, texh);
*(verts++) = dstrect->x + dstrect->w;
*(verts++) = dstrect->y;
*(verts++) = normtex(srcrect->x + srcrect->w, texw);
*(verts++) = normtex(srcrect->y, texh);
return 0;
}
static int
METAL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
const float texw = (float) texture->w;
const float texh = (float) texture->h;
const float rads = (float)(M_PI * (float) angle / 180.0f);
const float c = cosf(rads), s = sinf(rads);
float minu, maxu, minv, maxv;
const size_t vertlen = (sizeof (float) * 32);
float *verts;
// cheat and store this offset in (count) because it needs to be aligned in ways other fields don't and we aren't using count otherwise.
verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, CONSTANT_ALIGN(16), &cmd->data.draw.count);
if (!verts) {
return -1;
}
// transform matrix
SDL_memset(verts, '\0', sizeof (*verts) * 16);
verts[10] = verts[15] = 1.0f;
// rotation
verts[0] = c;
verts[1] = s;
verts[4] = -s;
verts[5] = c;
// translation
verts[12] = dstrect->x + center->x;
verts[13] = dstrect->y + center->y;
// rest of the vertices don't need the aggressive alignment. Pack them in.
verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
if (!verts) {
return -1;
}
minu = normtex(srcquad->x, texw);
maxu = normtex(srcquad->x + srcquad->w, texw);
minv = normtex(srcquad->y, texh);
maxv = normtex(srcquad->y + srcquad->h, texh);
if (flip & SDL_FLIP_HORIZONTAL) {
float tmp = maxu;
maxu = minu;
minu = tmp;
}
if (flip & SDL_FLIP_VERTICAL) {
float tmp = maxv;
maxv = minv;
minv = tmp;
}
/* Interleaved positions and texture coordinates */
*(verts++) = -center->x;
*(verts++) = dstrect->h - center->y;
*(verts++) = minu;
*(verts++) = maxv;
*(verts++) = -center->x;
*(verts++) = -center->y;
*(verts++) = minu;
*(verts++) = minv;
*(verts++) = dstrect->w - center->x;
*(verts++) = dstrect->h - center->y;
*(verts++) = maxu;
*(verts++) = maxv;
*(verts++) = dstrect->w - center->x;
*(verts++) = -center->y;
*(verts++) = maxu;
*(verts++) = minv;
return 0;
}
typedef struct
{
#if __has_feature(objc_arc)
@@ -1295,7 +1213,7 @@ typedef struct
size_t color_offset;
} METAL_DrawStateCache;
static void
static SDL_bool
SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader,
const size_t constants_offset, id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
{
@@ -1304,7 +1222,9 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
size_t first = cmd->data.draw.first;
id<MTLRenderPipelineState> newpipeline;
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer);
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer)) {
return SDL_FALSE;
}
if (statecache->viewport_dirty) {
MTLViewport viewport;
@@ -1358,9 +1278,10 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
}
[data.mtlcmdencoder setVertexBufferOffset:first atIndex:0]; /* position/texcoords */
return SDL_TRUE;
}
static void
static SDL_bool
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset,
id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
{
@@ -1368,7 +1289,9 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
SDL_Texture *texture = cmd->data.draw.texture;
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache);
if (!SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache)) {
return SDL_FALSE;
}
if (texture != statecache->texture) {
METAL_TextureData *oldtexturedata = NULL;
@@ -1386,6 +1309,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
}
statecache->texture = texture;
}
return SDL_TRUE;
}
static int
@@ -1483,6 +1407,7 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
// get new command encoder, set up with an initial clear operation.
// (this might fail, and future draw operations will notice.)
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex);
break;
}
@@ -1491,44 +1416,34 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
case SDL_RENDERCMD_DRAW_LINES: {
const size_t count = cmd->data.draw.count;
const MTLPrimitiveType primtype = (cmd->command == SDL_RENDERCMD_DRAW_POINTS) ? MTLPrimitiveTypePoint : MTLPrimitiveTypeLineStrip;
SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache);
[data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count];
break;
}
case SDL_RENDERCMD_FILL_RECTS: {
const size_t count = cmd->data.draw.count;
const size_t maxcount = UINT16_MAX / 4;
SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache);
if (count == 1) {
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
} else {
/* Our index buffer has 16 bit indices, so we can only draw
* 65k vertices (16k rects) at a time. */
for (size_t i = 0; i < count; i += maxcount) {
/* Set the vertex buffer offset for our current positions.
* The vertex buffer itself was bound in SetDrawState. */
[data.mtlcmdencoder setVertexBufferOffset:cmd->data.draw.first + i*sizeof(float)*8 atIndex:0];
[data.mtlcmdencoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:SDL_min(maxcount, count - i) * 6
indexType:MTLIndexTypeUInt16
indexBuffer:data.mtlbufquadindices
indexBufferOffset:0];
}
if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache)) {
[data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count];
}
break;
}
case SDL_RENDERCMD_COPY: {
SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache);
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
case SDL_RENDERCMD_FILL_RECTS: /* unused */
break;
}
case SDL_RENDERCMD_COPY_EX: {
SetCopyState(renderer, cmd, CONSTANTS_OFFSET_INVALID, mtlbufvertex, &statecache);
[data.mtlcmdencoder setVertexBuffer:mtlbufvertex offset:cmd->data.draw.count atIndex:3]; // transform
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
case SDL_RENDERCMD_COPY: /* unused */
break;
case SDL_RENDERCMD_COPY_EX: /* unused */
break;
case SDL_RENDERCMD_GEOMETRY: {
const size_t count = cmd->data.draw.count;
SDL_Texture *texture = cmd->data.draw.texture;
if (texture) {
if (SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) {
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count];
}
} else {
if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) {
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count];
}
}
break;
}
@@ -1546,7 +1461,9 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch)
{ @autoreleasepool {
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) {
return SDL_SetError("Failed to activate render command encoder (is your window in the background?");
}
[data.mtlcmdencoder endEncoding];
id<MTLTexture> mtltexture = data.mtlpassdesc.colorAttachments[0].texture;
@@ -1591,20 +1508,28 @@ static void
METAL_RenderPresent(SDL_Renderer * renderer)
{ @autoreleasepool {
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
SDL_bool ready = SDL_TRUE;
// If we don't have a command buffer, we can't present, so activate to get one.
if (data.mtlcmdencoder == nil) {
// We haven't even gotten a backbuffer yet? Clear it to black. Otherwise, load the existing data.
if (data.mtlbackbuffer == nil) {
MTLClearColor color = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f);
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil);
ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil);
} else {
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
}
}
[data.mtlcmdencoder endEncoding];
[data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer];
// If we don't have a drawable to present, don't try to present it.
// But we'll still try to commit the command buffer in case it was already enqueued.
if (ready) {
SDL_assert(data.mtlbackbuffer != nil);
[data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer];
}
[data.mtlcmdbuffer commit];
data.mtlcmdencoder = nil;
@@ -1647,11 +1572,34 @@ METAL_GetMetalLayer(SDL_Renderer * renderer)
static void *
METAL_GetMetalCommandEncoder(SDL_Renderer * renderer)
{ @autoreleasepool {
// note that data.mtlcmdencoder can be nil if METAL_ActivateRenderCommandEncoder fails.
// Before SDL 2.0.18, it might have returned a non-nil encoding that might not have been
// usable for presentation. Check your return values!
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
return (__bridge void*)data.mtlcmdencoder;
}}
static int
METAL_SetVSync(SDL_Renderer * renderer, const int vsync)
{
#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST
if (@available(macOS 10.13, *)) {
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
if (vsync) {
data.mtllayer.displaySyncEnabled = YES;
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
} else {
data.mtllayer.displaySyncEnabled = NO;
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
}
return 0;
}
#endif
return SDL_SetError("This Apple OS does not support displaySyncEnabled!");
}
static SDL_Renderer *
METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
{ @autoreleasepool {
@@ -1891,14 +1839,13 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->QueueSetDrawColor = METAL_QueueSetDrawColor;
renderer->QueueDrawPoints = METAL_QueueDrawPoints;
renderer->QueueDrawLines = METAL_QueueDrawLines;
renderer->QueueFillRects = METAL_QueueFillRects;
renderer->QueueCopy = METAL_QueueCopy;
renderer->QueueCopyEx = METAL_QueueCopyEx;
renderer->QueueGeometry = METAL_QueueGeometry;
renderer->RunCommandQueue = METAL_RunCommandQueue;
renderer->RenderReadPixels = METAL_RenderReadPixels;
renderer->RenderPresent = METAL_RenderPresent;
renderer->DestroyTexture = METAL_DestroyTexture;
renderer->DestroyRenderer = METAL_DestroyRenderer;
renderer->SetVSync = METAL_SetVSync;
renderer->GetMetalLayer = METAL_GetMetalLayer;
renderer->GetMetalCommandEncoder = METAL_GetMetalCommandEncoder;

View File

@@ -6,11 +6,13 @@ using namespace metal;
struct SolidVertexInput
{
float2 position [[attribute(0)]];
float4 color [[attribute(1)]];
};
struct SolidVertexOutput
{
float4 position [[position]];
float4 color;
float pointSize [[point_size]];
};
@@ -20,24 +22,27 @@ vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]],
{
SolidVertexOutput v;
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
v.color = in.color;
v.pointSize = 1.0f;
return v;
}
fragment float4 SDL_Solid_fragment(const device float4 &col [[buffer(0)]])
fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]])
{
return col;
return in.color;
}
struct CopyVertexInput
{
float2 position [[attribute(0)]];
float2 texcoord [[attribute(1)]];
float4 color [[attribute(1)]];
float2 texcoord [[attribute(2)]];
};
struct CopyVertexOutput
{
float4 position [[position]];
float4 color;
float2 texcoord;
};
@@ -47,16 +52,16 @@ vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]],
{
CopyVertexOutput v;
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
v.color = in.color;
v.texcoord = in.texcoord;
return v;
}
fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]],
const device float4 &col [[buffer(0)]],
texture2d<float> tex [[texture(0)]],
sampler s [[sampler(0)]])
{
return tex.sample(s, vert.texcoord) * col;
return tex.sample(s, vert.texcoord) * vert.color;
}
struct YUVDecode
@@ -68,7 +73,6 @@ struct YUVDecode
};
fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
const device float4 &col [[buffer(0)]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d_array<float> texUV [[texture(1)]],
@@ -81,11 +85,10 @@ fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
yuv += decode.offset;
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}
fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
const device float4 &col [[buffer(0)]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d<float> texUV [[texture(1)]],
@@ -97,11 +100,10 @@ fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
yuv += decode.offset;
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}
fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
const device float4 &col [[buffer(0)]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d<float> texUV [[texture(1)]],
@@ -113,5 +115,6 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
yuv += decode.offset;
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff