mojoshader_metal.c
author Caleb Cornett <caleb.cornett@outlook.com>
Sun, 12 Jan 2020 11:39:49 -0500
changeset 1229 3ecd29a50d9d
child 1240 ebb2b1e436f2
permissions -rw-r--r--
Metal Effect support!
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1229
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     1
/**
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     2
 * MojoShader; generate shader programs from bytecode of compiled
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     3
 *  Direct3D shaders.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     4
 *
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     5
 * Please see the file LICENSE.txt in the source's root directory.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     6
 *
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     7
 *  This file written by Ryan C. Gordon.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     8
 */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
     9
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    10
#if (defined(__APPLE__) && defined(__MACH__))
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    11
#define PLATFORM_APPLE 1
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    12
#include "TargetConditionals.h"
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    13
#define OBJC_OLD_DISPATCH_PROTOTYPES 1
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    14
#include <objc/message.h>
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    15
#define objc_msgSend_STR ((void* (*)(void*, void*, const char*))objc_msgSend)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    16
#define objc_msgSend_PTR ((void* (*)(void*, void*, void*))objc_msgSend)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    17
#define objc_msgSend_INT_PTR ((void* (*)(void*, void*, int, void*))objc_msgSend)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    18
#define objc_msgSend_PTR_PTR_PTR ((void* (*)(void*, void*, void*, void*, void*))objc_msgSend)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    19
#endif /* (defined(__APPLE__) && defined(__MACH__)) */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    20
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    21
#define __MOJOSHADER_INTERNAL__ 1
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    22
#include "mojoshader_internal.h"
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    23
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    24
typedef struct MOJOSHADER_mtlUniformBuffer MOJOSHADER_mtlUniformBuffer;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    25
typedef struct MOJOSHADER_mtlShader
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    26
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    27
    const MOJOSHADER_parseData *parseData;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    28
    MOJOSHADER_mtlUniformBuffer *ubo;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    29
    void *library; // MTLLibrary*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    30
    int numInternalBuffers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    31
} MOJOSHADER_mtlShader;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    32
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    33
// Error state...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    34
static char error_buffer[1024] = { '\0' };
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    35
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    36
static void set_error(const char *str)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    37
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    38
    snprintf(error_buffer, sizeof (error_buffer), "%s", str);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    39
} // set_error
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    40
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    41
static inline void out_of_memory(void)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    42
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    43
    set_error("out of memory");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    44
} // out_of_memory
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    45
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    46
// profile-specific implementations...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    47
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    48
#if SUPPORT_PROFILE_METAL && PLATFORM_APPLE
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    49
#ifdef MOJOSHADER_EFFECT_SUPPORT
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    50
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    51
/* Structs */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    52
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    53
typedef struct MOJOSHADER_mtlEffect
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    54
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    55
    MOJOSHADER_effect *effect;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    56
    unsigned int num_shaders;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    57
    MOJOSHADER_mtlShader *shaders;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    58
    unsigned int *shader_indices;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    59
    unsigned int num_preshaders;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    60
    unsigned int *preshader_indices;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    61
    MOJOSHADER_mtlShader *current_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    62
    MOJOSHADER_mtlShader *current_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    63
    MOJOSHADER_effectShader *current_vert_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    64
    MOJOSHADER_effectShader *current_frag_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    65
    MOJOSHADER_mtlShader *prev_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    66
    MOJOSHADER_mtlShader *prev_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    67
    void *library; // MTLLibrary*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    68
} MOJOSHADER_mtlEffect;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    69
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    70
typedef struct MOJOSHADER_mtlUniformBuffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    71
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    72
    void *device; // MTLDevice*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    73
    int bufferSize;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    74
    int numInternalBuffers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    75
    void **internalBuffers; // MTLBuffer*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    76
    int internalBufferSize;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    77
    int internalOffset;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    78
    int currentFrame;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    79
    int alreadyWritten;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    80
} MOJOSHADER_mtlUniformBuffer;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    81
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    82
typedef struct MOJOSHADER_mtlShaderState
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    83
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    84
    MOJOSHADER_mtlShader *vertexShader;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    85
    MOJOSHADER_mtlShader *fragmentShader;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    86
    void *vertexUniformBuffer; // MTLBuffer*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    87
    void *fragmentUniformBuffer; // MTLBuffer*
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    88
    int vertexUniformOffset;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    89
    int fragmentUniformOffset;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    90
} MOJOSHADER_mtlShaderState;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    91
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    92
/* Objective-C selector references */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    93
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    94
static void *classNSString = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    95
static void *selAlloc = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    96
static void *selInitWithUTF8String = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    97
static void *selUTF8String = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    98
static void *selLength = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
    99
static void *selContents = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   100
static void *selNewBufferWithLength = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   101
static void *selRelease = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   102
static void *selNewLibraryWithSource = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   103
static void *selLocalizedDescription = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   104
static void *selNewFunctionWithName = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   105
static void *selRetain = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   106
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   107
/* Helper functions */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   108
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   109
static void initSelectors(void)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   110
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   111
    classNSString = (void*) objc_getClass("NSString");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   112
    selAlloc = sel_registerName("alloc");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   113
    selInitWithUTF8String = sel_registerName("initWithUTF8String:");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   114
    selUTF8String = sel_registerName("UTF8String");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   115
    selLength = sel_registerName("length");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   116
    selContents = sel_registerName("contents");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   117
    selNewBufferWithLength = sel_registerName("newBufferWithLength:options:");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   118
    selRelease = sel_registerName("release");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   119
    selNewLibraryWithSource = sel_registerName("newLibraryWithSource:options:error:");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   120
    selLocalizedDescription = sel_registerName("localizedDescription");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   121
    selNewFunctionWithName = sel_registerName("newFunctionWithName:");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   122
    selRetain = sel_registerName("retain");
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   123
} // initSelectors
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   124
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   125
static void *cstr_to_nsstr(const char *str)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   126
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   127
    return objc_msgSend_STR(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   128
        objc_msgSend(classNSString, selAlloc),
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   129
        selInitWithUTF8String,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   130
        str
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   131
    );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   132
} // cstr_to_nsstr
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   133
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   134
static const char *nsstr_to_cstr(void *str)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   135
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   136
    return (char *) objc_msgSend(str, selUTF8String);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   137
} // nssstr_to_cstr
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   138
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   139
/* Linked list */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   140
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   141
typedef struct LLNODE {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   142
    MOJOSHADER_mtlUniformBuffer *data;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   143
    struct LLNODE *next;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   144
} LLNODE;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   145
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   146
static LLNODE *LL_append_node(LLNODE **baseNode,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   147
                              MOJOSHADER_malloc m,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   148
                              void *d)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   149
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   150
    LLNODE *prev = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   151
    LLNODE *node = *baseNode;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   152
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   153
    /* Append a node to the linked list. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   154
    while (node != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   155
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   156
        prev = node;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   157
        node = node->next;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   158
    } // while
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   159
    node = m(sizeof(LLNODE), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   160
    node->next = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   161
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   162
    /* Connect the old to the new. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   163
    if (prev != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   164
        prev->next = node;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   165
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   166
    /* Special case for the first node. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   167
    if (*baseNode == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   168
        *baseNode = node;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   169
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   170
    return node;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   171
} // LL_append_node
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   172
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   173
static void LL_remove_node(LLNODE **baseNode,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   174
                           MOJOSHADER_mtlUniformBuffer *data,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   175
                           MOJOSHADER_free f,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   176
                           void *d)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   177
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   178
    LLNODE *prev = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   179
    LLNODE *node = *baseNode;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   180
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   181
    /* Search for node with matching data pointer. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   182
    while (node != NULL && node->data != data)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   183
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   184
        prev = node;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   185
        node = node->next;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   186
    } // while
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   187
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   188
    if (node == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   189
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   190
        /* This should never happen. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   191
        assert(0);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   192
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   193
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   194
    /* Clear data pointer. The data must be freed separately. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   195
    node->data = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   196
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   197
    /* Connect the old to the new. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   198
    if (prev != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   199
        prev->next = node->next;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   200
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   201
    /* Special cases where the first node is removed. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   202
    if (prev == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   203
        *baseNode = (node->next != NULL) ? node->next : NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   204
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   205
    /* Free the node! */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   206
    f(node, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   207
} // LL_remove_node
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   208
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   209
/* Internal register utilities */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   210
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   211
// Max entries for each register file type...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   212
#define MAX_REG_FILE_F 8192
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   213
#define MAX_REG_FILE_I 2047
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   214
#define MAX_REG_FILE_B 2047
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   215
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   216
// The constant register files...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   217
// !!! FIXME: Man, it kills me how much memory this takes...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   218
// !!! FIXME:  ... make this dynamically allocated on demand.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   219
float vs_reg_file_f[MAX_REG_FILE_F * 4];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   220
int vs_reg_file_i[MAX_REG_FILE_I * 4];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   221
uint8 vs_reg_file_b[MAX_REG_FILE_B];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   222
float ps_reg_file_f[MAX_REG_FILE_F * 4];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   223
int ps_reg_file_i[MAX_REG_FILE_I * 4];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   224
uint8 ps_reg_file_b[MAX_REG_FILE_B];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   225
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   226
static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   227
                                       unsigned int *param_loc,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   228
                                       MOJOSHADER_symbol *symbols,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   229
                                       unsigned int symbol_count,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   230
                                       float *regf, int *regi, uint8 *regb)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   231
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   232
    int i, j, r, c;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   233
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   234
    i = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   235
    for (i = 0; i < symbol_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   236
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   237
        const MOJOSHADER_symbol *sym = &symbols[i];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   238
        const MOJOSHADER_effectValue *param = &params[param_loc[i]].value;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   239
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   240
        // float/int registers are vec4, so they have 4 elements each
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   241
        const uint32 start = sym->register_index << 2;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   242
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   243
        if (param->type.parameter_type == MOJOSHADER_SYMTYPE_FLOAT)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   244
            memcpy(regf + start, param->valuesF, sym->register_count << 4);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   245
        else if (sym->register_set == MOJOSHADER_SYMREGSET_FLOAT4)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   246
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   247
            // Structs are a whole different world...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   248
            if (param->type.parameter_class == MOJOSHADER_SYMCLASS_STRUCT)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   249
                memcpy(regf + start, param->valuesF, sym->register_count << 4);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   250
            else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   251
            {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   252
                // Sometimes int/bool parameters get thrown into float registers...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   253
                j = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   254
                do
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   255
                {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   256
                    c = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   257
                    do
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   258
                    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   259
                        regf[start + (j << 2) + c] = (float) param->valuesI[(j << 2) + c];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   260
                    } while (++c < param->type.columns);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   261
                } while (++j < sym->register_count);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   262
            } // else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   263
        } // else if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   264
        else if (sym->register_set == MOJOSHADER_SYMREGSET_INT4)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   265
            memcpy(regi + start, param->valuesI, sym->register_count << 4);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   266
        else if (sym->register_set == MOJOSHADER_SYMREGSET_BOOL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   267
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   268
            j = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   269
            r = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   270
            do
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   271
            {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   272
                c = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   273
                do
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   274
                {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   275
                    // regb is not a vec4, enjoy that 'start' bitshift! -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   276
                    regb[(start >> 2) + r + c] = param->valuesI[(j << 2) + c];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   277
                    c++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   278
                } while (c < param->type.columns && ((r + c) < sym->register_count));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   279
                r += c;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   280
                j++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   281
            } while (r < sym->register_count);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   282
        } // else if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   283
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   284
} // copy_parameter_data
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   285
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   286
/* Uniform buffer utilities */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   287
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   288
static inline int next_highest_alignment(int n)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   289
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   290
    #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_SIMULATOR
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   291
    int align = 16;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   292
    #else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   293
    int align = 256;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   294
    #endif
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   295
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   296
    return align * ((n + align - 1) / align);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   297
} // next_highest_alignment
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   298
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   299
static int UBO_buffer_length(void *buffer)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   300
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   301
    return (int) objc_msgSend(buffer, selLength);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   302
} // UBO_buffer_length
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   303
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   304
static void *UBO_buffer_contents(void *buffer)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   305
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   306
    return (void *) objc_msgSend(buffer, selContents);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   307
} // UBO_buffer_contents
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   308
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   309
static void *UBO_create_backing_buffer(MOJOSHADER_mtlUniformBuffer *ubo, int f)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   310
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   311
    void *oldBuffer = ubo->internalBuffers[f];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   312
    void *newBuffer = objc_msgSend_INT_PTR(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   313
        ubo->device,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   314
        selNewBufferWithLength,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   315
        ubo->internalBufferSize,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   316
        NULL
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   317
    );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   318
    if (oldBuffer != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   319
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   320
        // Copy over data from old buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   321
        memcpy(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   322
            UBO_buffer_contents(newBuffer),
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   323
            UBO_buffer_contents(oldBuffer),
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   324
            UBO_buffer_length(oldBuffer)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   325
        );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   326
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   327
        // Free the old buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   328
        objc_msgSend(oldBuffer, selRelease);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   329
    } //if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   330
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   331
    return newBuffer;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   332
} // UBO_create_backing_buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   333
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   334
static void UBO_predraw(MOJOSHADER_mtlUniformBuffer *ubo)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   335
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   336
    if (!ubo->alreadyWritten)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   337
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   338
        ubo->alreadyWritten = 1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   339
        return;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   340
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   341
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   342
    ubo->internalOffset += ubo->bufferSize;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   343
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   344
    int buflen = UBO_buffer_length(ubo->internalBuffers[ubo->currentFrame]);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   345
    if (ubo->internalOffset >= buflen)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   346
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   347
        // Double capacity when we're out of room
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   348
        if (ubo->internalOffset >= ubo->internalBufferSize)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   349
            ubo->internalBufferSize *= 2;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   350
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   351
        ubo->internalBuffers[ubo->currentFrame] =
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   352
            UBO_create_backing_buffer(ubo, ubo->currentFrame);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   353
    } //if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   354
} // UBO_predraw
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   355
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   356
static void UBO_end_frame(MOJOSHADER_mtlUniformBuffer *ubo)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   357
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   358
    ubo->internalOffset = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   359
    ubo->currentFrame = (ubo->currentFrame + 1) % ubo->numInternalBuffers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   360
    ubo->alreadyWritten = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   361
} // UBO_end_frame
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   362
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   363
LLNODE *ubos = NULL; /* global linked list of all active UBOs */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   364
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   365
static MOJOSHADER_mtlUniformBuffer *create_ubo(MOJOSHADER_mtlShader *shader,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   366
                                               void *mtlDevice,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   367
                                               MOJOSHADER_malloc m,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   368
                                               void *d)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   369
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   370
    int uniformCount = shader->parseData->uniform_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   371
    if (uniformCount == 0)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   372
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   373
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   374
    // Calculate how big we need to make the buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   375
    int buflen = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   376
    for (int i = 0; i < uniformCount; i += 1)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   377
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   378
        int arrayCount = shader->parseData->uniforms[i].array_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   379
        int uniformSize = 16;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   380
        if (shader->parseData->uniforms[i].type == MOJOSHADER_UNIFORM_BOOL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   381
            uniformSize = 1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   382
        buflen += (arrayCount ? arrayCount : 1) * uniformSize;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   383
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   384
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   385
    // Make the UBO
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   386
    MOJOSHADER_mtlUniformBuffer *ubo = (MOJOSHADER_mtlUniformBuffer *) m(sizeof(MOJOSHADER_mtlUniformBuffer), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   387
    ubo->device = mtlDevice;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   388
    ubo->alreadyWritten = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   389
    ubo->bufferSize = next_highest_alignment(buflen);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   390
    ubo->currentFrame = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   391
    ubo->numInternalBuffers = shader->numInternalBuffers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   392
    ubo->internalBufferSize = ubo->bufferSize * 16; // pre-allocate some extra room!
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   393
    ubo->internalBuffers = m(ubo->numInternalBuffers * sizeof(void*), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   394
    ubo->internalOffset = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   395
    for (int i = 0; i < ubo->numInternalBuffers; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   396
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   397
        ubo->internalBuffers[i] = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   398
        ubo->internalBuffers[i] = UBO_create_backing_buffer(ubo, i);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   399
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   400
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   401
    /* Add the UBO to the global list so it can be updated. */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   402
    LLNODE *node = LL_append_node(&ubos, m, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   403
    node->data = ubo;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   404
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   405
    return ubo;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   406
} // create_ubo
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   407
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   408
static void dealloc_ubo(MOJOSHADER_mtlShader *shader,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   409
                        MOJOSHADER_free f,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   410
                        void* d)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   411
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   412
    if (shader->ubo == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   413
        return;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   414
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   415
    LL_remove_node(&ubos, shader->ubo, f, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   416
    for (int i = 0; i < shader->ubo->numInternalBuffers; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   417
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   418
        objc_msgSend(shader->ubo->internalBuffers[i], selRelease);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   419
        shader->ubo->internalBuffers[i] = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   420
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   421
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   422
    f(shader->ubo->internalBuffers, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   423
    f(shader->ubo, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   424
} // dealloc_ubo
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   425
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   426
static void *get_uniform_buffer(MOJOSHADER_mtlShader *shader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   427
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   428
    if (shader == NULL || shader->ubo == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   429
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   430
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   431
    return shader->ubo->internalBuffers[shader->ubo->currentFrame];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   432
} // get_uniform_buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   433
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   434
static int get_uniform_offset(MOJOSHADER_mtlShader *shader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   435
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   436
    if (shader == NULL || shader->ubo == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   437
        return 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   438
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   439
    return shader->ubo->internalOffset;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   440
} // get_uniform_offset
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   441
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   442
static void update_uniform_buffer(MOJOSHADER_mtlShader *shader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   443
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   444
    if (shader == NULL || shader->ubo == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   445
        return;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   446
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   447
    float *regF; int *regI; uint8 *regB;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   448
    if (shader->parseData->shader_type == MOJOSHADER_TYPE_VERTEX)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   449
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   450
        regF = vs_reg_file_f;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   451
        regI = vs_reg_file_i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   452
        regB = vs_reg_file_b;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   453
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   454
    else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   455
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   456
        regF = ps_reg_file_f;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   457
        regI = ps_reg_file_i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   458
        regB = ps_reg_file_b;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   459
    } // else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   460
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   461
    UBO_predraw(shader->ubo);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   462
    void *buf = shader->ubo->internalBuffers[shader->ubo->currentFrame];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   463
    void *contents = UBO_buffer_contents(buf) + shader->ubo->internalOffset;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   464
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   465
    int offset = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   466
    for (int i = 0; i < shader->parseData->uniform_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   467
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   468
        int idx = shader->parseData->uniforms[i].index;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   469
        int arrayCount = shader->parseData->uniforms[i].array_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   470
        int size = arrayCount ? arrayCount : 1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   471
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   472
        switch (shader->parseData->uniforms[i].type)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   473
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   474
            case MOJOSHADER_UNIFORM_FLOAT:
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   475
                memcpy(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   476
                    contents + (offset * 16),
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   477
                    &regF[4 * idx],
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   478
                    size * 16
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   479
                );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   480
                break;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   481
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   482
            case MOJOSHADER_UNIFORM_INT:
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   483
                // !!! FIXME: Need a test case
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   484
                memcpy(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   485
                    contents + (offset * 16),
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   486
                    &regI[4 * idx],
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   487
                    size * 16
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   488
                );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   489
                break;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   490
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   491
            case MOJOSHADER_UNIFORM_BOOL:
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   492
                // !!! FIXME: Need a test case
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   493
                memcpy(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   494
                    contents + offset,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   495
                    &regB[idx],
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   496
                    size
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   497
                );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   498
                break;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   499
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   500
            default:
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   501
                assert(0); // This should never happen.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   502
                break;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   503
        } // switch
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   504
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   505
        offset += size;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   506
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   507
} // update_uniform_buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   508
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   509
/* Public API */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   510
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   511
MOJOSHADER_mtlEffect *MOJOSHADER_mtlCompileEffect(MOJOSHADER_effect *effect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   512
                                                  void *mtlDevice,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   513
                                                  int numBackingBuffers)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   514
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   515
    int i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   516
    MOJOSHADER_malloc m = effect->malloc;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   517
    MOJOSHADER_free f = effect->free;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   518
    void *d = effect->malloc_data;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   519
    int current_shader = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   520
    int current_preshader = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   521
    int src_len = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   522
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   523
    // Make sure the Objective-C selectors have been initialized...
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   524
    if (selAlloc == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   525
        initSelectors();
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   526
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   527
    MOJOSHADER_mtlEffect *retval = (MOJOSHADER_mtlEffect *) m(sizeof (MOJOSHADER_mtlEffect), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   528
    if (retval == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   529
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   530
        out_of_memory();
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   531
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   532
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   533
    memset(retval, '\0', sizeof (MOJOSHADER_mtlEffect));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   534
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   535
    // Count the number of shaders before allocating
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   536
    for (i = 0; i < effect->object_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   537
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   538
        MOJOSHADER_effectObject *object = &effect->objects[i];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   539
        if (object->type == MOJOSHADER_SYMTYPE_PIXELSHADER
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   540
         || object->type == MOJOSHADER_SYMTYPE_VERTEXSHADER)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   541
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   542
            if (object->shader.is_preshader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   543
                retval->num_preshaders++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   544
            else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   545
            {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   546
                retval->num_shaders++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   547
                src_len += object->shader.shader->output_len;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   548
            } // else
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   549
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   550
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   551
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   552
    // Alloc shader source buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   553
    char *shader_source = (char *) m(src_len + 1, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   554
    memset(shader_source, '\0', src_len + 1);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   555
    int src_pos = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   556
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   557
    // Copy all the source text into the buffer
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   558
    for (i = 0; i < effect->object_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   559
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   560
        MOJOSHADER_effectObject *object = &effect->objects[i];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   561
        if (object->type == MOJOSHADER_SYMTYPE_PIXELSHADER
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   562
         || object->type == MOJOSHADER_SYMTYPE_VERTEXSHADER)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   563
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   564
            if (!object->shader.is_preshader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   565
            {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   566
                int output_len = object->shader.shader->output_len;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   567
                memcpy(&shader_source[src_pos], object->shader.shader->output, output_len);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   568
                src_pos += output_len;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   569
            } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   570
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   571
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   572
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   573
    // Handle texcoord0 -> point_coord conversion
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   574
    if (strstr(shader_source, "[[point_size]]"))
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   575
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   576
        // !!! FIXME: This assumes all texcoord0 attributes in the effect are
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   577
        // !!! FIXME:  actually point coords! It ain't necessarily so! -caleb
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   578
        const char *repl = "[[  point_coord  ]]";
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   579
        char *ptr;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   580
        while ((ptr = strstr(shader_source, "[[user(texcoord0)]]")))
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   581
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   582
            memcpy(ptr, repl, strlen(repl));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   583
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   584
            // float4 -> float2
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   585
            int spaces = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   586
            while (spaces < 2)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   587
                if (*(ptr--) == ' ')
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   588
                    spaces++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   589
            memcpy(ptr, "2", sizeof(char));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   590
        } // while
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   591
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   592
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   593
    // Alloc shader information
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   594
    retval->shaders = (MOJOSHADER_mtlShader *) m(retval->num_shaders * sizeof (MOJOSHADER_mtlShader), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   595
    if (retval->shaders == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   596
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   597
        f(retval, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   598
        out_of_memory();
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   599
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   600
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   601
    memset(retval->shaders, '\0', retval->num_shaders * sizeof (MOJOSHADER_mtlShader));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   602
    retval->shader_indices = (unsigned int *) m(retval->num_shaders * sizeof (unsigned int), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   603
    if (retval->shader_indices == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   604
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   605
        f(retval->shaders, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   606
        f(retval, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   607
        out_of_memory();
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   608
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   609
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   610
    memset(retval->shader_indices, '\0', retval->num_shaders * sizeof (unsigned int));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   611
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   612
    // Alloc preshader information
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   613
    if (retval->num_preshaders > 0)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   614
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   615
        retval->preshader_indices = (unsigned int *) m(retval->num_preshaders * sizeof (unsigned int), d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   616
        if (retval->preshader_indices == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   617
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   618
            f(retval->shaders, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   619
            f(retval->shader_indices, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   620
            f(retval, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   621
            out_of_memory();
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   622
            return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   623
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   624
        memset(retval->preshader_indices, '\0', retval->num_preshaders * sizeof (unsigned int));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   625
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   626
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   627
    // Compile the source into a library
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   628
    void *compileError = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   629
    void *shader_source_ns = cstr_to_nsstr(shader_source);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   630
    void *library = objc_msgSend_PTR_PTR_PTR(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   631
        mtlDevice,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   632
        selNewLibraryWithSource,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   633
        shader_source_ns,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   634
        NULL,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   635
        &compileError
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   636
    );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   637
    retval->library = library;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   638
    f(shader_source, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   639
    objc_msgSend(shader_source_ns, selRelease);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   640
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   641
    if (library == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   642
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   643
        // Set the error
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   644
        void *error_nsstr = objc_msgSend(compileError, selLocalizedDescription);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   645
        set_error(nsstr_to_cstr(error_nsstr));
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   646
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   647
        goto compile_shader_fail;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   648
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   649
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   650
    // Run through the shaders again, tracking the object indices
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   651
    for (i = 0; i < effect->object_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   652
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   653
        MOJOSHADER_effectObject *object = &effect->objects[i];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   654
        if (object->type == MOJOSHADER_SYMTYPE_PIXELSHADER
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   655
         || object->type == MOJOSHADER_SYMTYPE_VERTEXSHADER)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   656
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   657
            if (object->shader.is_preshader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   658
            {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   659
                retval->preshader_indices[current_preshader++] = i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   660
                continue;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   661
            } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   662
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   663
            MOJOSHADER_mtlShader *curshader = &retval->shaders[current_shader];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   664
            curshader->parseData = object->shader.shader;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   665
            curshader->numInternalBuffers = numBackingBuffers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   666
            curshader->ubo = create_ubo(curshader, mtlDevice, m, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   667
            curshader->library = library;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   668
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   669
            retval->shader_indices[current_shader] = i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   670
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   671
            current_shader++;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   672
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   673
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   674
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   675
    retval->effect = effect;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   676
    return retval;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   677
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   678
compile_shader_fail:
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   679
    f(retval->shader_indices, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   680
    f(retval->shaders, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   681
    f(retval, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   682
    return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   683
} // MOJOSHADER_mtlCompileEffect
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   684
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   685
void MOJOSHADER_mtlDeleteEffect(MOJOSHADER_mtlEffect *mtlEffect)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   686
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   687
    MOJOSHADER_free f = mtlEffect->effect->free;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   688
    void *d = mtlEffect->effect->malloc_data;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   689
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   690
    int i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   691
    for (i = 0; i < mtlEffect->num_shaders; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   692
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   693
        /* Release the uniform buffers */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   694
        dealloc_ubo(&mtlEffect->shaders[i], f, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   695
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   696
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   697
    /* Release the library */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   698
    objc_msgSend(mtlEffect->library, selRelease);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   699
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   700
    f(mtlEffect->shader_indices, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   701
    f(mtlEffect->preshader_indices, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   702
    f(mtlEffect, d);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   703
} // MOJOSHADER_mtlDeleteEffect
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   704
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   705
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   706
void MOJOSHADER_mtlEffectBegin(MOJOSHADER_mtlEffect *mtlEffect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   707
                               unsigned int *numPasses,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   708
                               int saveShaderState,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   709
                               MOJOSHADER_effectStateChanges *stateChanges)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   710
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   711
    *numPasses = mtlEffect->effect->current_technique->pass_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   712
    mtlEffect->effect->restore_shader_state = saveShaderState;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   713
    mtlEffect->effect->state_changes = stateChanges;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   714
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   715
    if (mtlEffect->effect->restore_shader_state)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   716
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   717
        mtlEffect->prev_vert = mtlEffect->current_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   718
        mtlEffect->prev_frag = mtlEffect->current_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   719
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   720
} // MOJOSHADER_mtlEffectBegin
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   721
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   722
// Predeclare
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   723
void MOJOSHADER_mtlEffectCommitChanges(MOJOSHADER_mtlEffect *mtlEffect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   724
                                       MOJOSHADER_mtlShaderState *shState);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   725
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   726
void MOJOSHADER_mtlEffectBeginPass(MOJOSHADER_mtlEffect *mtlEffect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   727
                                   unsigned int pass,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   728
                                   MOJOSHADER_mtlShaderState *shState)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   729
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   730
    int i, j;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   731
    MOJOSHADER_effectPass *curPass;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   732
    MOJOSHADER_effectState *state;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   733
    MOJOSHADER_effectShader *rawVert = mtlEffect->current_vert_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   734
    MOJOSHADER_effectShader *rawFrag = mtlEffect->current_frag_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   735
    int has_preshader = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   736
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   737
    assert(shState != NULL);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   738
    assert(mtlEffect->effect->current_pass == -1);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   739
    mtlEffect->effect->current_pass = pass;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   740
    curPass = &mtlEffect->effect->current_technique->passes[pass];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   741
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   742
    // !!! FIXME: I bet this could be stored at parse/compile time. -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   743
    for (i = 0; i < curPass->state_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   744
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   745
        state = &curPass->states[i];
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   746
        #define ASSIGN_SHADER(stype, raw, mtls) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   747
            (state->type == stype) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   748
            { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   749
                j = 0; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   750
                do \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   751
                { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   752
                    if (*state->value.valuesI == mtlEffect->shader_indices[j]) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   753
                    { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   754
                        raw = &mtlEffect->effect->objects[*state->value.valuesI].shader; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   755
                        mtlEffect->mtls = &mtlEffect->shaders[j]; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   756
                        break; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   757
                    } \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   758
                    else if (mtlEffect->num_preshaders > 0 \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   759
                          && *state->value.valuesI == mtlEffect->preshader_indices[j]) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   760
                    { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   761
                        raw = &mtlEffect->effect->objects[*state->value.valuesI].shader; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   762
                        has_preshader = 1; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   763
                        break; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   764
                    } \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   765
                } while (++j < mtlEffect->num_shaders); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   766
            }
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   767
        if ASSIGN_SHADER(MOJOSHADER_RS_VERTEXSHADER, rawVert, current_vert)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   768
        else if ASSIGN_SHADER(MOJOSHADER_RS_PIXELSHADER, rawFrag, current_frag)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   769
        #undef ASSIGN_SHADER
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   770
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   771
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   772
    mtlEffect->effect->state_changes->render_state_changes = curPass->states;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   773
    mtlEffect->effect->state_changes->render_state_change_count = curPass->state_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   774
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   775
    mtlEffect->current_vert_raw = rawVert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   776
    mtlEffect->current_frag_raw = rawFrag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   777
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   778
    /* If this effect pass has an array of shaders, we get to wait until
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   779
     * CommitChanges to actually bind the final shaders.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   780
     * -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   781
     */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   782
    if (!has_preshader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   783
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   784
        if (mtlEffect->current_vert != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   785
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   786
            MOJOSHADER_mtlShader *vert = mtlEffect->current_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   787
            shState->vertexShader = vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   788
            shState->vertexUniformBuffer = get_uniform_buffer(vert);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   789
            shState->vertexUniformOffset = get_uniform_offset(vert);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   790
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   791
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   792
        if (mtlEffect->current_frag != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   793
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   794
            MOJOSHADER_mtlShader *frag = mtlEffect->current_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   795
            shState->fragmentShader = frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   796
            shState->fragmentUniformBuffer = get_uniform_buffer(frag);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   797
            shState->fragmentUniformOffset = get_uniform_offset(frag);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   798
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   799
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   800
        if (mtlEffect->current_vert_raw != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   801
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   802
            mtlEffect->effect->state_changes->vertex_sampler_state_changes = rawVert->samplers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   803
            mtlEffect->effect->state_changes->vertex_sampler_state_change_count = rawVert->sampler_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   804
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   805
        if (mtlEffect->current_frag_raw != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   806
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   807
            mtlEffect->effect->state_changes->sampler_state_changes = rawFrag->samplers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   808
            mtlEffect->effect->state_changes->sampler_state_change_count = rawFrag->sampler_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   809
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   810
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   811
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   812
    MOJOSHADER_mtlEffectCommitChanges(mtlEffect, shState);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   813
} // MOJOSHADER_mtlEffectBeginPass
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   814
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   815
void MOJOSHADER_mtlEffectCommitChanges(MOJOSHADER_mtlEffect *mtlEffect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   816
                                       MOJOSHADER_mtlShaderState *shState)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   817
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   818
    MOJOSHADER_effectShader *rawVert = mtlEffect->current_vert_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   819
    MOJOSHADER_effectShader *rawFrag = mtlEffect->current_frag_raw;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   820
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   821
    /* Used for shader selection from preshaders */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   822
    int i, j;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   823
    MOJOSHADER_effectValue *param;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   824
    float selector;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   825
    int shader_object;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   826
    int selector_ran = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   827
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   828
    /* For effect passes with arrays of shaders, we have to run a preshader
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   829
     * that determines which shader to use, based on a parameter's value.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   830
     * -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   831
     */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   832
    // !!! FIXME: We're just running the preshaders every time. Blech. -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   833
    #define SELECT_SHADER_FROM_PRESHADER(raw, mtls) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   834
        if (raw != NULL && raw->is_preshader) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   835
        { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   836
            i = 0; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   837
            do \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   838
            { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   839
                param = &mtlEffect->effect->params[raw->preshader_params[i]].value; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   840
                for (j = 0; j < (param->value_count >> 2); j++) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   841
                    memcpy(raw->preshader->registers + raw->preshader->symbols[i].register_index + j, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   842
                           param->valuesI + (j << 2), \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   843
                           param->type.columns << 2); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   844
            } while (++i < raw->preshader->symbol_count); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   845
            MOJOSHADER_runPreshader(raw->preshader, &selector); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   846
            shader_object = mtlEffect->effect->params[raw->params[0]].value.valuesI[(int) selector]; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   847
            raw = &mtlEffect->effect->objects[shader_object].shader; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   848
            i = 0; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   849
            do \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   850
            { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   851
                if (shader_object == mtlEffect->shader_indices[i]) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   852
                { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   853
                    mtls = &mtlEffect->shaders[i]; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   854
                    break; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   855
                } \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   856
            } while (++i < mtlEffect->num_shaders); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   857
            selector_ran = 1; \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   858
        }
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   859
    SELECT_SHADER_FROM_PRESHADER(rawVert, mtlEffect->current_vert)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   860
    SELECT_SHADER_FROM_PRESHADER(rawFrag, mtlEffect->current_frag)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   861
    #undef SELECT_SHADER_FROM_PRESHADER
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   862
    if (selector_ran)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   863
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   864
        if (mtlEffect->current_vert != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   865
            shState->vertexShader = mtlEffect->current_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   866
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   867
        if (mtlEffect->current_frag != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   868
            shState->fragmentShader = mtlEffect->current_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   869
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   870
        if (mtlEffect->current_vert_raw != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   871
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   872
            mtlEffect->effect->state_changes->vertex_sampler_state_changes = rawVert->samplers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   873
            mtlEffect->effect->state_changes->vertex_sampler_state_change_count = rawVert->sampler_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   874
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   875
        if (mtlEffect->current_frag_raw != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   876
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   877
            mtlEffect->effect->state_changes->sampler_state_changes = rawFrag->samplers;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   878
            mtlEffect->effect->state_changes->sampler_state_change_count = rawFrag->sampler_count;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   879
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   880
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   881
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   882
    /* This is where parameters are copied into the constant buffers.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   883
     * If you're looking for where things slow down immensely, look at
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   884
     * the copy_parameter_data() and MOJOSHADER_runPreshader() functions.
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   885
     * -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   886
     */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   887
    // !!! FIXME: We're just copying everything every time. Blech. -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   888
    // !!! FIXME: We're just running the preshaders every time. Blech. -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   889
    // !!! FIXME: Will the preshader ever want int/bool registers? -flibit
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   890
    #define COPY_PARAMETER_DATA(raw, stage) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   891
        if (raw != NULL) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   892
        { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   893
            copy_parameter_data(mtlEffect->effect->params, raw->params, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   894
                                raw->shader->symbols, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   895
                                raw->shader->symbol_count, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   896
                                stage##_reg_file_f, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   897
                                stage##_reg_file_i, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   898
                                stage##_reg_file_b); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   899
            if (raw->shader->preshader) \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   900
            { \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   901
                copy_parameter_data(mtlEffect->effect->params, raw->preshader_params, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   902
                                    raw->shader->preshader->symbols, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   903
                                    raw->shader->preshader->symbol_count, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   904
                                    raw->shader->preshader->registers, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   905
                                    NULL, \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   906
                                    NULL); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   907
                MOJOSHADER_runPreshader(raw->shader->preshader, stage##_reg_file_f); \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   908
            } \
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   909
        }
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   910
    COPY_PARAMETER_DATA(rawVert, vs)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   911
    COPY_PARAMETER_DATA(rawFrag, ps)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   912
    #undef COPY_PARAMETER_DATA
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   913
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   914
    update_uniform_buffer(shState->vertexShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   915
    shState->vertexUniformBuffer = get_uniform_buffer(shState->vertexShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   916
    shState->vertexUniformOffset = get_uniform_offset(shState->vertexShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   917
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   918
    update_uniform_buffer(shState->fragmentShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   919
    shState->fragmentUniformBuffer = get_uniform_buffer(shState->fragmentShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   920
    shState->fragmentUniformOffset = get_uniform_offset(shState->fragmentShader);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   921
} // MOJOSHADER_mtlEffectCommitChanges
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   922
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   923
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   924
void MOJOSHADER_mtlEffectEndPass(MOJOSHADER_mtlEffect *mtlEffect)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   925
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   926
    assert(mtlEffect->effect->current_pass != -1);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   927
    mtlEffect->effect->current_pass = -1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   928
} // MOJOSHADER_mtlEffectEndPass
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   929
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   930
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   931
void MOJOSHADER_mtlEffectEnd(MOJOSHADER_mtlEffect *mtlEffect,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   932
                             MOJOSHADER_mtlShaderState *shState)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   933
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   934
    if (mtlEffect->effect->restore_shader_state)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   935
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   936
        mtlEffect->effect->restore_shader_state = 0;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   937
        shState->vertexShader = mtlEffect->prev_vert;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   938
        shState->fragmentShader = mtlEffect->prev_frag;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   939
        shState->vertexUniformBuffer = get_uniform_buffer(mtlEffect->prev_vert);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   940
        shState->fragmentUniformBuffer = get_uniform_buffer(mtlEffect->prev_frag);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   941
        shState->vertexUniformOffset = get_uniform_offset(mtlEffect->prev_vert);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   942
        shState->fragmentUniformOffset = get_uniform_offset(mtlEffect->prev_frag);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   943
    } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   944
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   945
    mtlEffect->effect->state_changes = NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   946
} // MOJOSHADER_mtlEffectEnd
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   947
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   948
void *MOJOSHADER_mtlGetFunctionHandle(MOJOSHADER_mtlShader *shader)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   949
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   950
    if (shader == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   951
        return NULL;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   952
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   953
    void *fnname = cstr_to_nsstr(shader->parseData->mainfn);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   954
    void *ret = objc_msgSend_PTR(
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   955
        shader->library,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   956
        selNewFunctionWithName,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   957
        fnname
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   958
    );
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   959
    objc_msgSend(fnname, selRelease);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   960
    objc_msgSend(ret, selRetain);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   961
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   962
    return ret;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   963
} // MOJOSHADER_mtlGetFunctionHandle
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   964
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   965
void MOJOSHADER_mtlEndFrame()
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   966
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   967
    LLNODE *node = ubos;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   968
    while (node != NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   969
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   970
        UBO_end_frame((MOJOSHADER_mtlUniformBuffer *) node->data);
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   971
        node = node->next;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   972
    } // while
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   973
} // MOJOSHADER_mtlEndFrame
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   974
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   975
int MOJOSHADER_mtlGetVertexAttribLocation(MOJOSHADER_mtlShader *vert,
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   976
                                          MOJOSHADER_usage usage, int index)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   977
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   978
    if (vert == NULL)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   979
        return -1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   980
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   981
    for (int i = 0; i < vert->parseData->attribute_count; i++)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   982
    {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   983
        if (vert->parseData->attributes[i].usage == usage
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   984
            && vert->parseData->attributes[i].index == index)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   985
        {
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   986
            return i;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   987
        } // if
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   988
    } // for
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   989
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   990
    // failure, couldn't find requested attribute
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   991
    return -1;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   992
} // MOJOSHADER_mtlGetVertexAttribLocation
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   993
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   994
const char *MOJOSHADER_mtlGetError(void)
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   995
{
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   996
    return error_buffer;
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   997
} // MOJOSHADER_mtlGetError
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   998
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
   999
#endif /* MOJOSHADER_EFFECT_SUPPORT */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
  1000
#endif /* SUPPORT_PROFILE_METAL && PLATFORM_APPLE */
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
  1001
3ecd29a50d9d Metal Effect support!
Caleb Cornett <caleb.cornett@outlook.com>
parents:
diff changeset
  1002
// end of mojoshader_metal.c ...