1133 lines
33 KiB
C
1133 lines
33 KiB
C
|
|
//------------------------------------------------------------------------
|
|
// Manual pointer size checking functions
|
|
//------------------------------------------------------------------------
|
|
|
|
u64 orca_gles_check_cstring(IM3Runtime runtime, const char* ptr)
|
|
{
|
|
uint32_t memorySize = 0;
|
|
char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0);
|
|
|
|
//NOTE: Here we are guaranteed that ptr is in [ memory ; memory + memorySize [
|
|
// hence (memory + memorySize) - ptr is representable by size_t and <= memorySize
|
|
size_t maxLen = (memory + memorySize) - ptr;
|
|
|
|
u64 len = strnlen(ptr, maxLen);
|
|
|
|
if(len == maxLen)
|
|
{
|
|
//NOTE: string overflows wasm memory, return a length that will trigger the bounds check
|
|
len = maxLen + 1;
|
|
}
|
|
return(len+1); //include null-terminator
|
|
}
|
|
|
|
u64 orca_gl_type_size(GLenum type)
|
|
{
|
|
u64 size = 8;
|
|
switch(type)
|
|
{
|
|
case GL_UNSIGNED_BYTE:
|
|
case GL_BYTE:
|
|
size = sizeof(GLbyte);
|
|
break;
|
|
|
|
case GL_UNSIGNED_SHORT:
|
|
case GL_SHORT:
|
|
case GL_HALF_FLOAT:
|
|
size = sizeof(GLshort);
|
|
break;
|
|
|
|
case GL_UNSIGNED_INT:
|
|
case GL_INT:
|
|
case GL_FIXED:
|
|
case GL_INT_2_10_10_10_REV:
|
|
case GL_UNSIGNED_INT_2_10_10_10_REV:
|
|
size = sizeof(GLint);
|
|
break;
|
|
|
|
case GL_FLOAT:
|
|
size = sizeof(GLfloat);
|
|
break;
|
|
|
|
case GL_DOUBLE:
|
|
size = sizeof(GLdouble);
|
|
break;
|
|
|
|
default:
|
|
ORCA_ASSERT(0, "unknown GLenum type %i", type);
|
|
}
|
|
|
|
return(size);
|
|
}
|
|
|
|
u64 orca_gl_format_count(GLenum format)
|
|
{
|
|
u64 count = 4;
|
|
switch(format)
|
|
{
|
|
case GL_RED:
|
|
case GL_RED_INTEGER:
|
|
case GL_DEPTH_COMPONENT:
|
|
case GL_STENCIL_INDEX:
|
|
case GL_LUMINANCE:
|
|
case GL_ALPHA:
|
|
count = 1;
|
|
break;
|
|
|
|
case GL_RG:
|
|
case GL_RG_INTEGER:
|
|
case GL_DEPTH_STENCIL:
|
|
case GL_LUMINANCE_ALPHA:
|
|
count = 2;
|
|
break;
|
|
|
|
case GL_RGB:
|
|
case GL_RGB_INTEGER:
|
|
count = 3;
|
|
break;
|
|
|
|
case GL_RGBA:
|
|
case GL_RGBA_INTEGER:
|
|
count = 4;
|
|
break;
|
|
|
|
default:
|
|
ORCA_ASSERT(0, "unknow GLenum format %i", format);
|
|
}
|
|
|
|
return(count);
|
|
}
|
|
|
|
typedef struct orca_gles_impl_limits
|
|
{
|
|
bool init;
|
|
int maxDrawBuffers;
|
|
int numCompressedTextureFormats;
|
|
int numProgramBinaryFormats;
|
|
int numShaderBinaryFormats;
|
|
//...
|
|
} orca_gles_impl_limits;
|
|
|
|
orca_gles_impl_limits __orcaGLESImplLimits = {0};
|
|
|
|
u64 orca_glGet_data_length(GLenum pname)
|
|
{
|
|
if(!__orcaGLESImplLimits.init)
|
|
{
|
|
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &__orcaGLESImplLimits.maxDrawBuffers);
|
|
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &__orcaGLESImplLimits.numCompressedTextureFormats);
|
|
glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &__orcaGLESImplLimits.numProgramBinaryFormats);
|
|
glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &__orcaGLESImplLimits.numShaderBinaryFormats);
|
|
}
|
|
u64 count = 8;
|
|
|
|
if(pname >= GL_DRAW_BUFFER0 && pname < GL_DRAW_BUFFER0 + __orcaGLESImplLimits.maxDrawBuffers)
|
|
{
|
|
count = 1;
|
|
}
|
|
else
|
|
{
|
|
switch(pname)
|
|
{
|
|
case GL_ACTIVE_TEXTURE:
|
|
case GL_ALPHA_BITS:
|
|
case GL_ARRAY_BUFFER_BINDING:
|
|
case GL_BLEND:
|
|
case GL_BLEND_DST_ALPHA:
|
|
case GL_BLEND_DST_RGB:
|
|
case GL_BLEND_EQUATION_ALPHA:
|
|
case GL_BLEND_EQUATION_RGB:
|
|
case GL_BLEND_SRC_ALPHA:
|
|
case GL_BLEND_SRC_RGB:
|
|
case GL_BLUE_BITS:
|
|
case GL_CONTEXT_FLAGS:
|
|
case GL_CONTEXT_ROBUST_ACCESS:
|
|
case GL_COPY_READ_BUFFER_BINDING:
|
|
case GL_COPY_WRITE_BUFFER_BINDING:
|
|
case GL_CULL_FACE:
|
|
case GL_CULL_FACE_MODE:
|
|
case GL_CURRENT_PROGRAM:
|
|
case GL_DEBUG_GROUP_STACK_DEPTH:
|
|
case GL_DEBUG_LOGGED_MESSAGES:
|
|
case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
|
|
case GL_DEPTH_BITS:
|
|
case GL_DEPTH_CLEAR_VALUE:
|
|
case GL_DEPTH_FUNC:
|
|
case GL_DEPTH_TEST:
|
|
case GL_DEPTH_WRITEMASK:
|
|
case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
|
|
case GL_DITHER:
|
|
case GL_DRAW_FRAMEBUFFER_BINDING:
|
|
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
|
|
case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS:
|
|
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
|
|
case GL_FRONT_FACE:
|
|
case GL_GENERATE_MIPMAP_HINT:
|
|
case GL_GREEN_BITS:
|
|
case GL_IMAGE_BINDING_LAYERED:
|
|
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
|
|
case GL_IMPLEMENTATION_COLOR_READ_TYPE:
|
|
case GL_LAYER_PROVOKING_VERTEX:
|
|
case GL_LINE_WIDTH:
|
|
case GL_MAJOR_VERSION:
|
|
case GL_MAX_3D_TEXTURE_SIZE:
|
|
case GL_MAX_ARRAY_TEXTURE_LAYERS:
|
|
case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
|
|
case GL_MAX_COLOR_ATTACHMENTS:
|
|
|
|
case GL_MAX_COMBINED_ATOMIC_COUNTERS:
|
|
case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_COMBINED_UNIFORM_BLOCKS:
|
|
case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
|
|
case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
|
|
case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
|
|
case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
|
|
case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
|
|
case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
|
|
case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
|
|
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
|
|
case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
|
|
case GL_MAX_DEBUG_LOGGED_MESSAGES:
|
|
case GL_MAX_DEBUG_MESSAGE_LENGTH:
|
|
case GL_MAX_DEPTH_TEXTURE_SAMPLES:
|
|
case GL_MAX_DRAW_BUFFERS:
|
|
case GL_MAX_ELEMENT_INDEX:
|
|
case GL_MAX_ELEMENTS_INDICES:
|
|
case GL_MAX_ELEMENTS_VERTICES:
|
|
case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
|
|
case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
|
|
case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
|
|
case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET:
|
|
case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
|
|
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
|
|
case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
|
|
case GL_MAX_FRAMEBUFFER_HEIGHT:
|
|
case GL_MAX_FRAMEBUFFER_LAYERS:
|
|
case GL_MAX_FRAMEBUFFER_SAMPLES:
|
|
case GL_MAX_FRAMEBUFFER_WIDTH:
|
|
case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_GEOMETRY_ATOMIC_COUNTERS:
|
|
case GL_MAX_GEOMETRY_IMAGE_UNIFORMS:
|
|
case GL_MAX_GEOMETRY_INPUT_COMPONENTS:
|
|
case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS:
|
|
case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
|
|
case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
|
|
case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
|
|
case GL_MAX_GEOMETRY_UNIFORM_BLOCKS:
|
|
case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS:
|
|
case GL_MAX_INTEGER_SAMPLES:
|
|
case GL_MAX_LABEL_LENGTH:
|
|
case GL_MAX_PROGRAM_TEXEL_OFFSET:
|
|
case GL_MAX_RENDERBUFFER_SIZE:
|
|
case GL_MAX_SAMPLE_MASK_WORDS:
|
|
case GL_MAX_SAMPLES:
|
|
case GL_MAX_SERVER_WAIT_TIMEOUT:
|
|
case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
|
|
case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
|
|
case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS:
|
|
case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS:
|
|
case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS:
|
|
case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS:
|
|
case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS:
|
|
case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS:
|
|
case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS:
|
|
case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS:
|
|
case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS:
|
|
case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS:
|
|
case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS:
|
|
case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS:
|
|
case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS:
|
|
case GL_MAX_TESS_GEN_LEVEL:
|
|
case GL_MAX_TESS_PATCH_COMPONENTS:
|
|
case GL_MAX_TEXTURE_BUFFER_SIZE:
|
|
case GL_MAX_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_TEXTURE_LOD_BIAS:
|
|
case GL_MAX_TEXTURE_SIZE:
|
|
case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
|
|
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
|
|
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
|
|
case GL_MAX_UNIFORM_BLOCK_SIZE:
|
|
case GL_MAX_UNIFORM_BUFFER_BINDINGS:
|
|
case GL_MAX_UNIFORM_LOCATIONS:
|
|
case GL_MAX_VARYING_COMPONENTS:
|
|
case GL_MAX_VARYING_VECTORS:
|
|
case GL_MAX_VERTEX_ATOMIC_COUNTERS:
|
|
case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_VERTEX_ATTRIB_BINDINGS:
|
|
case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
|
|
case GL_MAX_VERTEX_ATTRIBS:
|
|
case GL_MAX_VERTEX_IMAGE_UNIFORMS:
|
|
case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
|
|
case GL_MAX_VERTEX_UNIFORM_BLOCKS:
|
|
case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
|
|
case GL_MAX_VERTEX_UNIFORM_VECTORS:
|
|
case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET:
|
|
case GL_MIN_PROGRAM_TEXEL_OFFSET:
|
|
case GL_MIN_SAMPLE_SHADING_VALUE:
|
|
case GL_MINOR_VERSION:
|
|
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
|
case GL_NUM_EXTENSIONS:
|
|
case GL_NUM_PROGRAM_BINARY_FORMATS:
|
|
case GL_NUM_SHADER_BINARY_FORMATS:
|
|
case GL_PACK_ALIGNMENT:
|
|
case GL_PACK_ROW_LENGTH:
|
|
case GL_PACK_SKIP_PIXELS:
|
|
case GL_PACK_SKIP_ROWS:
|
|
case GL_PATCH_VERTICES:
|
|
case GL_PIXEL_PACK_BUFFER_BINDING:
|
|
case GL_PIXEL_UNPACK_BUFFER_BINDING:
|
|
case GL_POLYGON_OFFSET_FACTOR:
|
|
case GL_POLYGON_OFFSET_FILL:
|
|
case GL_POLYGON_OFFSET_UNITS:
|
|
case GL_PRIMITIVE_RESTART_FIXED_INDEX:
|
|
case GL_PROGRAM_PIPELINE_BINDING:
|
|
case GL_RASTERIZER_DISCARD:
|
|
case GL_READ_BUFFER:
|
|
case GL_READ_FRAMEBUFFER_BINDING:
|
|
case GL_RED_BITS:
|
|
case GL_RENDERBUFFER_BINDING:
|
|
case GL_RESET_NOTIFICATION_STRATEGY:
|
|
case GL_SAMPLE_ALPHA_TO_COVERAGE:
|
|
case GL_SAMPLE_BUFFERS:
|
|
case GL_SAMPLE_COVERAGE:
|
|
case GL_SAMPLE_COVERAGE_INVERT:
|
|
case GL_SAMPLE_COVERAGE_VALUE:
|
|
case GL_SAMPLE_MASK_VALUE:
|
|
case GL_SAMPLE_SHADING:
|
|
case GL_SAMPLER_BINDING:
|
|
case GL_SAMPLES:
|
|
case GL_SCISSOR_TEST:
|
|
case GL_SHADER_COMPILER:
|
|
case GL_SHADER_STORAGE_BUFFER_BINDING:
|
|
case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
|
|
case GL_SHADER_STORAGE_BUFFER_SIZE:
|
|
case GL_SHADER_STORAGE_BUFFER_START:
|
|
case GL_STENCIL_BACK_FAIL:
|
|
case GL_STENCIL_BACK_FUNC:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
|
|
case GL_STENCIL_BACK_PASS_DEPTH_PASS:
|
|
case GL_STENCIL_BACK_REF:
|
|
case GL_STENCIL_BACK_VALUE_MASK:
|
|
case GL_STENCIL_BACK_WRITEMASK:
|
|
case GL_STENCIL_BITS:
|
|
case GL_STENCIL_CLEAR_VALUE:
|
|
case GL_STENCIL_FAIL:
|
|
case GL_STENCIL_FUNC:
|
|
case GL_STENCIL_PASS_DEPTH_FAIL:
|
|
case GL_STENCIL_PASS_DEPTH_PASS:
|
|
case GL_STENCIL_REF:
|
|
case GL_STENCIL_TEST:
|
|
case GL_STENCIL_VALUE_MASK:
|
|
case GL_STENCIL_WRITEMASK:
|
|
case GL_SUBPIXEL_BITS:
|
|
case GL_TEXTURE_BINDING_2D:
|
|
case GL_TEXTURE_BINDING_2D_ARRAY:
|
|
case GL_TEXTURE_BINDING_3D:
|
|
case GL_TEXTURE_BINDING_BUFFER:
|
|
case GL_TEXTURE_BINDING_CUBE_MAP:
|
|
case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
|
|
case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
|
|
case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
|
|
case GL_TEXTURE_BUFFER_BINDING:
|
|
case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
|
|
case GL_TRANSFORM_FEEDBACK_BINDING:
|
|
case GL_TRANSFORM_FEEDBACK_ACTIVE:
|
|
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
|
|
case GL_TRANSFORM_FEEDBACK_PAUSED:
|
|
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
|
|
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
|
|
case GL_UNIFORM_BUFFER_BINDING:
|
|
case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
|
|
case GL_UNIFORM_BUFFER_SIZE:
|
|
case GL_UNIFORM_BUFFER_START:
|
|
case GL_UNPACK_ALIGNMENT:
|
|
case GL_UNPACK_IMAGE_HEIGHT:
|
|
case GL_UNPACK_ROW_LENGTH:
|
|
case GL_UNPACK_SKIP_IMAGES:
|
|
case GL_UNPACK_SKIP_PIXELS:
|
|
case GL_UNPACK_SKIP_ROWS:
|
|
case GL_VERTEX_ARRAY_BINDING:
|
|
case GL_VERTEX_BINDING_DIVISOR:
|
|
case GL_VERTEX_BINDING_OFFSET:
|
|
case GL_VERTEX_BINDING_STRIDE:
|
|
case GL_TEXTURE_2D:
|
|
case GL_TEXTURE_3D:
|
|
count = 1;
|
|
break;
|
|
|
|
case GL_ALIASED_LINE_WIDTH_RANGE:
|
|
case GL_ALIASED_POINT_SIZE_RANGE:
|
|
case GL_DEPTH_RANGE:
|
|
case GL_MAX_VIEWPORT_DIMS:
|
|
case GL_MULTISAMPLE_LINE_WIDTH_RANGE:
|
|
count = 2;
|
|
break;
|
|
|
|
case GL_BLEND_COLOR:
|
|
case GL_COLOR_CLEAR_VALUE:
|
|
case GL_COLOR_WRITEMASK:
|
|
case GL_SCISSOR_BOX:
|
|
case GL_VIEWPORT:
|
|
count = 4;
|
|
break;
|
|
|
|
case GL_PRIMITIVE_BOUNDING_BOX:
|
|
count = 8;
|
|
break;
|
|
|
|
case GL_COMPRESSED_TEXTURE_FORMATS:
|
|
count = __orcaGLESImplLimits.numCompressedTextureFormats;
|
|
break;
|
|
|
|
case GL_PROGRAM_BINARY_FORMATS:
|
|
count = __orcaGLESImplLimits.numProgramBinaryFormats;
|
|
break;
|
|
|
|
case GL_SHADER_BINARY_FORMATS:
|
|
count = __orcaGLESImplLimits.numShaderBinaryFormats;
|
|
break;
|
|
|
|
default:
|
|
ORCA_ASSERT(0, "unknown GLenum pname %i", pname);
|
|
break;
|
|
}
|
|
}
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glDrawElements_indices_length(IM3Runtime runtime, GLsizei count, GLenum type)
|
|
{
|
|
return(orca_gl_type_size(type)*count);
|
|
}
|
|
|
|
u64 orca_glGetBooleanv_data_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glGet_data_length(pname));
|
|
}
|
|
|
|
u64 orca_glGetBufferParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetFloatv_data_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glGet_data_length(pname));
|
|
}
|
|
u64 orca_glGetFramebufferAttachmentParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetIntegerv_data_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glGet_data_length(pname));
|
|
}
|
|
u64 orca_glGetProgramiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetRenderbufferParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetShaderiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
|
|
u64 orca_glTexParameter_params_length_generic(GLenum pname)
|
|
{
|
|
u64 count = 4;
|
|
if(pname == GL_TEXTURE_BORDER_COLOR)
|
|
{
|
|
count = 4;
|
|
}
|
|
else
|
|
{
|
|
count = 1;
|
|
}
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glGetTexParameterfv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glTexParameter_params_length_generic(pname));
|
|
}
|
|
|
|
u64 orca_glGetTexParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glTexParameter_params_length_generic(pname));
|
|
}
|
|
|
|
u64 orca_glReadPixels_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height)
|
|
{
|
|
u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format);
|
|
return(count);
|
|
}
|
|
u64 orca_glTexImage2D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height)
|
|
{
|
|
u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format);
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glTexParameterfv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glTexParameter_params_length_generic(pname));
|
|
}
|
|
u64 orca_glTexParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glTexParameter_params_length_generic(pname));
|
|
}
|
|
u64 orca_glTexSubImage2D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height)
|
|
{
|
|
u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format);
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glDrawRangeElements_indices_length(IM3Runtime runtime, GLsizei count, GLenum type)
|
|
{
|
|
return(count*orca_gl_type_size(type));
|
|
}
|
|
u64 orca_glTexImage3D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth)
|
|
{
|
|
u64 count = width*height*depth*orca_gl_type_size(type)*orca_gl_format_count(format);
|
|
return(count);
|
|
}
|
|
u64 orca_glTexSubImage3D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth)
|
|
{
|
|
u64 count = width*height*depth*orca_gl_type_size(type)*orca_gl_format_count(format);
|
|
return(count);
|
|
}
|
|
u64 orca_glGetQueryiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetQueryObjectuiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetIntegeri_v_data_length(IM3Runtime runtime, GLenum target)
|
|
{
|
|
return(orca_glGet_data_length(target));
|
|
}
|
|
u64 orca_glVertexAttribIPointer_pointer_length(IM3Runtime runtime, GLint size, GLenum type, GLsizei stride)
|
|
{
|
|
//WARN: pointer param of glVertexAttribPointer is actually treated as an offset,
|
|
// so, we don't need to check if this points to valid memory ??
|
|
return(0);
|
|
}
|
|
|
|
u64 orca_glClearBuffer_value_length_generic(GLenum buffer)
|
|
{
|
|
u64 count = 4;
|
|
switch(buffer)
|
|
{
|
|
case GL_COLOR:
|
|
count = 4;
|
|
break;
|
|
|
|
case GL_DEPTH:
|
|
case GL_STENCIL:
|
|
count = 1;
|
|
break;
|
|
|
|
default:
|
|
ORCA_ASSERT(0, "invalid buffer enum for glClearBuffer()");
|
|
}
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glClearBufferiv_value_length(IM3Runtime runtime, GLenum buffer)
|
|
{
|
|
return(orca_glClearBuffer_value_length_generic(buffer));
|
|
}
|
|
u64 orca_glClearBufferuiv_value_length(IM3Runtime runtime, GLenum buffer)
|
|
{
|
|
return(orca_glClearBuffer_value_length_generic(buffer));
|
|
}
|
|
u64 orca_glClearBufferfv_value_length(IM3Runtime runtime, GLenum buffer)
|
|
{
|
|
return(orca_glClearBuffer_value_length_generic(buffer));
|
|
}
|
|
|
|
u64 orca_glGetUniformIndices_uniformIndices_length(IM3Runtime runtime, GLsizei uniformCount)
|
|
{
|
|
return(uniformCount);
|
|
}
|
|
u64 orca_glGetActiveUniformsiv_params_length(IM3Runtime runtime, GLsizei uniformCount, GLenum pname)
|
|
{
|
|
return(uniformCount);
|
|
}
|
|
|
|
u64 orca_glGetActiveUniformBlockiv_params_length(IM3Runtime runtime, GLuint program, GLuint uniformBlockIndex, GLenum pname)
|
|
{
|
|
u64 count;
|
|
if(pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
|
|
{
|
|
GLint param;
|
|
glGetActiveUniformBlockiv(program, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ¶m);
|
|
count = param;
|
|
}
|
|
else
|
|
{
|
|
count = 1;
|
|
}
|
|
return(count);
|
|
}
|
|
u64 orca_glDrawElementsInstanced_indices_length(IM3Runtime runtime, GLsizei count, GLenum type)
|
|
{
|
|
return(count*orca_gl_type_size(type));
|
|
}
|
|
u64 orca_glGetInteger64v_data_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glGet_data_length(pname));
|
|
}
|
|
u64 orca_glGetInteger64i_v_data_length(IM3Runtime runtime, GLenum target)
|
|
{
|
|
return(orca_glGet_data_length(target));
|
|
}
|
|
u64 orca_glGetBufferParameteri64v_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
|
|
u64 orca_glSamplerParameter_param_length_generic(GLenum pname)
|
|
{
|
|
//NOTE: same as texture parameter pnames
|
|
return(orca_glTexParameter_params_length_generic(pname));
|
|
}
|
|
|
|
u64 orca_glSamplerParameteriv_param_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glSamplerParameter_param_length_generic(pname));
|
|
}
|
|
u64 orca_glSamplerParameterfv_param_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glSamplerParameter_param_length_generic(pname));
|
|
}
|
|
u64 orca_glGetSamplerParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glSamplerParameter_param_length_generic(pname));
|
|
}
|
|
u64 orca_glGetSamplerParameterfv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(orca_glSamplerParameter_param_length_generic(pname));
|
|
}
|
|
u64 orca_glGetFramebufferParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetProgramInterfaceiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
|
|
u64 orca_glGetProgramPipelineiv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetBooleani_v_data_length(IM3Runtime runtime, GLenum target)
|
|
{
|
|
return(orca_glSamplerParameter_param_length_generic(target));
|
|
}
|
|
u64 orca_glGetMultisamplefv_val_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
return(2);
|
|
}
|
|
u64 orca_glGetTexLevelParameteriv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
u64 orca_glGetTexLevelParameterfv_params_length(IM3Runtime runtime, GLenum pname)
|
|
{
|
|
//NOTE: all pnames return a single value in 3.1
|
|
return(1);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Uniforms size checking
|
|
//------------------------------------------------------------------------
|
|
|
|
u64 orca_glGetUniform_params_length_generic(GLuint program, GLint location)
|
|
{
|
|
//NOTE: This is super stupid but we can't get the size (or index) of a uniform directly from its location,
|
|
// so we have to iterate through all uniforms...
|
|
GLint maxUniformName = 0;
|
|
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformName);
|
|
|
|
int uniformCount = 0;
|
|
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
|
|
|
|
mem_arena_scope scratch = mem_scratch_begin();
|
|
char* name = mem_arena_alloc(scratch.arena, maxUniformName+1);
|
|
|
|
u64 count = 0;
|
|
bool found = false;
|
|
|
|
for(int i=0; i<uniformCount; i++)
|
|
{
|
|
GLsizei nameLength = 0;
|
|
GLint uniformSize = 0;
|
|
GLenum uniformType = 0;
|
|
glGetActiveUniform(program, i, maxUniformName, &nameLength, &uniformSize, &uniformType, name);
|
|
GLint uniformLocation = glGetUniformLocation(program, name);
|
|
|
|
if(uniformLocation == location)
|
|
{
|
|
count = uniformSize;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
ORCA_ASSERT(found, "uniform location %i not found for program %i", location, program);
|
|
|
|
mem_scratch_end(scratch);
|
|
return(count);
|
|
}
|
|
|
|
u64 orca_glGetUniformfv_params_length(IM3Runtime runtime, GLuint program, GLint location)
|
|
{
|
|
return(orca_glGetUniform_params_length_generic(program, location));
|
|
}
|
|
|
|
u64 orca_glGetUniformiv_params_length(IM3Runtime runtime, GLuint program, GLint location)
|
|
{
|
|
return(orca_glGetUniform_params_length_generic(program, location));
|
|
}
|
|
|
|
u64 orca_glGetUniformuiv_params_length(IM3Runtime runtime, GLuint program, GLint location)
|
|
{
|
|
return(orca_glGetUniform_params_length_generic(program, location));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Null-terminated parameters checking
|
|
//------------------------------------------------------------------------
|
|
|
|
u64 orca_glGetFragDataLocation_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
u64 orca_glGetUniformBlockIndex_uniformBlockName_length(IM3Runtime runtime, const GLchar* uniformBlockName)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, uniformBlockName));
|
|
}
|
|
|
|
u64 orca_glGetProgramResourceIndex_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
u64 orca_glGetProgramResourceLocation_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
u64 orca_glBindAttribLocation_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
u64 orca_glGetAttribLocation_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
u64 orca_glGetUniformLocation_name_length(IM3Runtime runtime, const GLchar* name)
|
|
{
|
|
return(orca_gles_check_cstring(runtime, name));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Draw indirect length checks
|
|
//------------------------------------------------------------------------
|
|
|
|
typedef struct
|
|
{
|
|
u32 count;
|
|
u32 primCount;
|
|
u32 first;
|
|
u32 reserved;
|
|
} DrawArraysIndirectCommand;
|
|
|
|
u64 orca_glDrawArraysIndirect_indirect_length(IM3Runtime runtime, const void* indirect)
|
|
{
|
|
return(sizeof(DrawArraysIndirectCommand));
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
u32 count;
|
|
u32 instanceCount;
|
|
u32 firstIndex;
|
|
i32 baseVertex;
|
|
u32 reservedMustBeZero;
|
|
} DrawElementsIndirectCommand;
|
|
|
|
u64 orca_glDrawElementsIndirect_indirect_length(IM3Runtime runtime, const void* indirect)
|
|
{
|
|
return(sizeof(DrawElementsIndirectCommand));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Fully manual bindings
|
|
//------------------------------------------------------------------------
|
|
|
|
const void* glShaderSource_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)
|
|
{
|
|
i32 shader = *(i32*)&_sp[0];
|
|
i32 count = *(i32*)&_sp[1];
|
|
i32 stringArrayOffset = *(i32*)&_sp[2];
|
|
i32 lengthArrayOffset = *(i32*)&_sp[3];
|
|
|
|
int* stringOffsetArray = (int*)((char*)_mem + stringArrayOffset);
|
|
const char** stringArray = (const char**)mem_arena_alloc_array(mem_scratch(), char*, count);
|
|
for(int i=0; i<count; i++)
|
|
{
|
|
stringArray[i] = (char*)_mem + stringOffsetArray[i];
|
|
}
|
|
|
|
int* lengthArray = lengthArrayOffset ? (int*)((char*)_mem + lengthArrayOffset) : 0;
|
|
|
|
glShaderSource(shader, count, stringArray, lengthArray);
|
|
return(0);
|
|
}
|
|
|
|
const void* glGetVertexAttribPointerv_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
GLuint index = *(i32*)&_sp[0];
|
|
GLenum pname = *(i32*)&_sp[1];
|
|
i32* pointer = (i32*)((char*)_mem + *(u32*)&_sp[2]);
|
|
{
|
|
ORCA_ASSERT(((char*)pointer >= (char*)_mem) && (((char*)pointer - (char*)_mem) < m3_GetMemorySize(runtime)),
|
|
"parameter 'pointer' is out of bounds");
|
|
ORCA_ASSERT((char*)pointer + sizeof(i32) <= ((char*)_mem + m3_GetMemorySize(runtime)),
|
|
"parameter 'pointer' overflows wasm memory");
|
|
}
|
|
void* rawPointer = 0;
|
|
glGetVertexAttribPointerv(index, pname, &rawPointer);
|
|
|
|
//NOTE: pointer is actually a _byte offset_ into a GPU buffer. So we do _not_ convert it to a wasm pointer,
|
|
// but we need to truncate it to u32 size...
|
|
//WARN: can OpenGL return a byte offset > UINT_MAX ?
|
|
*pointer = (i32)(intptr_t)rawPointer;
|
|
return(0);
|
|
}
|
|
|
|
const void* glVertexAttribPointer_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
GLuint index = *(u32*)&_sp[0];
|
|
GLint size = *(i32*)&_sp[1];
|
|
GLenum type = *(i32*)&_sp[2];
|
|
GLboolean normalized = (GLboolean)*(i32*)&_sp[3];
|
|
GLsizei stride = *(i32*)&_sp[4];
|
|
|
|
//NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER,
|
|
// or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays,
|
|
// we just disable those.
|
|
|
|
GLint boundBuffer = 0;
|
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer);
|
|
|
|
if(boundBuffer != 0)
|
|
{
|
|
//NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer
|
|
const void* pointer = (void*)(intptr_t)*(u32*)&_sp[5];
|
|
|
|
glVertexAttribPointer(index, size, type, normalized, stride, pointer);
|
|
}
|
|
else
|
|
{
|
|
//NOTE: we crash here before letting ANGLE crash because vertex attrib pointer is not set
|
|
ORCA_ASSERT("Calling glVertexAttribPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca.");
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
const void* glVertexAttribIPointer_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
GLuint index = *(u32*)&_sp[0];
|
|
GLint size = *(i32*)&_sp[1];
|
|
GLenum type = *(i32*)&_sp[2];
|
|
GLsizei stride = *(i32*)&_sp[3];
|
|
|
|
//NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER,
|
|
// or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays,
|
|
// we just disable those.
|
|
|
|
GLint boundBuffer = 0;
|
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer);
|
|
|
|
if(boundBuffer != 0)
|
|
{
|
|
//NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer
|
|
const void* pointer = (void*)(intptr_t)*(u32*)&_sp[4];
|
|
|
|
glVertexAttribIPointer(index, size, type, stride, pointer);
|
|
}
|
|
else
|
|
{
|
|
ORCA_ASSERT(0, "Calling glVertexAttribIPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca.");
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
const void* glGetUniformIndices_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
GLuint program = (GLuint)*(i32*)&_sp[0];
|
|
GLsizei uniformCount = (GLsizei)*(i32*)&_sp[1];
|
|
u32* uniformNames = (u32*)((char*)_mem + *(u32*)&_sp[2]);
|
|
GLuint * uniformIndices = (GLuint *)((char*)_mem + *(u32*)&_sp[3]);
|
|
|
|
u64 memorySize = m3_GetMemorySize(runtime);
|
|
//NOTE: check size of uniformNames
|
|
{
|
|
ORCA_ASSERT(((char*)uniformNames >= (char*)_mem) && (((char*)uniformNames - (char*)_mem) < memorySize),
|
|
"parameter 'uniformNames' is out of bounds");
|
|
ORCA_ASSERT((char*)uniformNames + uniformCount * sizeof(u32) <= ((char*)_mem + memorySize),
|
|
"parameter 'uniformNames' overflows wasm memory");
|
|
}
|
|
//NOTE: check each individual uniformNames
|
|
mem_arena_scope scratch = mem_scratch_begin();
|
|
|
|
char** uniformNamesRaw = mem_arena_alloc_array(scratch.arena, char*, uniformCount);
|
|
for(int i=0; i<uniformCount; i++)
|
|
{
|
|
char* raw = ((char*)_mem + uniformNames[i]);
|
|
ORCA_ASSERT(raw >= (char*)_mem && (raw - (char*)_mem) < memorySize, "uniformName[%i] is out of bounds", i);
|
|
|
|
u64 len = orca_gles_check_cstring(runtime, raw);
|
|
|
|
ORCA_ASSERT(raw + len <= ((char*)_mem + memorySize), "uniformName[%i] overflows wasm memory", i);
|
|
|
|
uniformNamesRaw[i] = raw;
|
|
}
|
|
|
|
//NOTE: check size of uniformIndices
|
|
{
|
|
ORCA_ASSERT(((char*)uniformIndices >= (char*)_mem) && (((char*)uniformIndices - (char*)_mem) < memorySize),
|
|
"parameter 'uniformIndices' is out of bounds");
|
|
ORCA_ASSERT((char*)uniformIndices + uniformCount * sizeof(GLuint) <= ((char*)_mem + memorySize),
|
|
"parameter 'uniformIndices' overflows wasm memory");
|
|
}
|
|
|
|
glGetUniformIndices(program, uniformCount, (const GLchar* const*)uniformNamesRaw, uniformIndices);
|
|
|
|
mem_scratch_end(scratch);
|
|
return(0);
|
|
}
|
|
|
|
typedef struct orca_gl_getstring_entry
|
|
{
|
|
u32 offset;
|
|
u32 len;
|
|
} orca_gl_getstring_entry;
|
|
|
|
GLenum ORCA_GL_GETSTRING_NAMES[] = {
|
|
GL_EXTENSIONS,
|
|
GL_VENDOR,
|
|
GL_RENDERER,
|
|
GL_VERSION,
|
|
GL_SHADING_LANGUAGE_VERSION
|
|
};
|
|
|
|
enum {
|
|
ORCA_GL_GETSTRING_ENTRY_COUNT = sizeof(ORCA_GL_GETSTRING_NAMES)/sizeof(GLenum)
|
|
};
|
|
|
|
typedef struct orca_gl_getstring_info
|
|
{
|
|
bool init;
|
|
|
|
orca_gl_getstring_entry entries[ORCA_GL_GETSTRING_ENTRY_COUNT];
|
|
|
|
u32 indexedEntryCount;
|
|
orca_gl_getstring_entry* indexedEntries;
|
|
|
|
} orca_gl_getstring_info;
|
|
|
|
orca_gl_getstring_info __orcaGLGetStringInfo = {0};
|
|
|
|
void orca_gl_getstring_init(orca_gl_getstring_info* info, char* memory)
|
|
{
|
|
u32 totalSize = 0;
|
|
const char* strings[ORCA_GL_GETSTRING_ENTRY_COUNT] = {0};
|
|
|
|
for(int i=0; i<ORCA_GL_GETSTRING_ENTRY_COUNT; i++)
|
|
{
|
|
strings[i] = (const char*)glGetString(ORCA_GL_GETSTRING_NAMES[i]);
|
|
if(strings[i])
|
|
{
|
|
info->entries[i].len = strlen(strings[i]) + 1;
|
|
totalSize += info->entries[i].len;
|
|
}
|
|
}
|
|
|
|
glGetIntegerv(GL_NUM_EXTENSIONS, (GLint*)&info->indexedEntryCount);
|
|
mem_arena_scope scratch = mem_scratch_begin();
|
|
const char** extensions = mem_arena_alloc(scratch.arena, info->indexedEntryCount);
|
|
|
|
//NOTE: we will hold this until program terminates
|
|
info->indexedEntries = malloc_array(orca_gl_getstring_entry, info->indexedEntryCount);
|
|
|
|
for(int i=0; i<info->indexedEntryCount; i++)
|
|
{
|
|
extensions[i] = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
|
if(extensions[i])
|
|
{
|
|
info->indexedEntries[i].len = strlen(extensions[i])+1;
|
|
totalSize += info->indexedEntries[i].len;
|
|
}
|
|
}
|
|
|
|
u32 wasmIndex = orca_mem_grow(totalSize);
|
|
|
|
for(int i=0; i<ORCA_GL_GETSTRING_ENTRY_COUNT; i++)
|
|
{
|
|
if(strings[i])
|
|
{
|
|
info->entries[i].offset = wasmIndex;
|
|
memcpy(memory + wasmIndex, strings[i], info->entries[i].len);
|
|
|
|
wasmIndex += info->entries[i].len;
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<info->indexedEntryCount; i++)
|
|
{
|
|
if(extensions[i])
|
|
{
|
|
info->indexedEntries[i].offset = wasmIndex;
|
|
memcpy(memory + wasmIndex, extensions[i], info->indexedEntries[i].len);
|
|
wasmIndex += info->indexedEntries[i].len;
|
|
}
|
|
}
|
|
|
|
mem_scratch_end(scratch);
|
|
|
|
info->init = true;
|
|
}
|
|
|
|
const void* glGetString_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
if(!__orcaGLGetStringInfo.init)
|
|
{
|
|
uint32_t memorySize = 0;
|
|
char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0);
|
|
orca_gl_getstring_init(&__orcaGLGetStringInfo, memory);
|
|
}
|
|
|
|
GLenum name = (GLenum)*(i32*)&_sp[1];
|
|
*(u32*)&_sp[0] = 0;
|
|
|
|
for(int i=0; i<ORCA_GL_GETSTRING_ENTRY_COUNT; i++)
|
|
{
|
|
if(name == ORCA_GL_GETSTRING_NAMES[i])
|
|
{
|
|
*(u32*)&_sp[0] = __orcaGLGetStringInfo.entries[i].offset;
|
|
break;
|
|
}
|
|
}
|
|
//NOTE: we still call glGetString so that it can set errors if name is incorrect
|
|
glGetString(name);
|
|
return(0);
|
|
}
|
|
|
|
const void* glGetStringi_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem)
|
|
{
|
|
if(!__orcaGLGetStringInfo.init)
|
|
{
|
|
uint32_t memorySize = 0;
|
|
char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0);
|
|
orca_gl_getstring_init(&__orcaGLGetStringInfo, memory);
|
|
}
|
|
|
|
GLenum name = (GLenum)*(i32*)&_sp[1];
|
|
GLuint index = (GLuint)*(i32*)&_sp[2];
|
|
|
|
*(u32*)&_sp[0] = 0;
|
|
if(name == GL_EXTENSIONS && index < __orcaGLGetStringInfo.indexedEntryCount)
|
|
{
|
|
*(u32*)&_sp[0] = __orcaGLGetStringInfo.indexedEntries[index].offset;
|
|
}
|
|
|
|
//NOTE: we still call glGetString so that it can set errors if name is incorrect
|
|
glGetStringi(name, index);
|
|
|
|
return(0);
|
|
}
|
|
|
|
int manual_link_gles_api(IM3Module module)
|
|
{
|
|
#define M3_LINK_ERROR_HANDLING(name) \
|
|
if(res != m3Err_none && res != m3Err_functionLookupFailed) \
|
|
{ \
|
|
log_error("Couldn't link function " #name " (%s)\n", res); \
|
|
ret = -1; \
|
|
}
|
|
|
|
M3Result res;
|
|
int ret = 0;
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glShaderSource", "v(iiii)", glShaderSource_stub);
|
|
M3_LINK_ERROR_HANDLING(glShaderSource)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glGetUniformIndices", "v(iiii)", glGetUniformIndices_stub);
|
|
M3_LINK_ERROR_HANDLING(glGetUniformIndices)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glGetVertexAttribPointerv", "v(iii)", glGetVertexAttribPointerv_stub);
|
|
M3_LINK_ERROR_HANDLING(glGetVertexAttribPointerv)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glGetString", "i(i)", glGetString_stub);
|
|
M3_LINK_ERROR_HANDLING(glGetGetString)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glGetStringi", "i(ii)", glGetStringi_stub);
|
|
M3_LINK_ERROR_HANDLING(glGetStringi)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glVertexAttribPointer", "v(iiiiii)", glVertexAttribPointer_stub);
|
|
M3_LINK_ERROR_HANDLING(glVertexAttribPointer)
|
|
|
|
res = m3_LinkRawFunction(module, "*", "glVertexAttribIPointer", "v(iiiii)", glVertexAttribIPointer_stub);
|
|
M3_LINK_ERROR_HANDLING(glVertexAttribIPointer)
|
|
|
|
#undef M3_LINK_ERROR_HANDLING
|
|
|
|
return(ret);
|
|
}
|