New upstream version 25.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2020-03-25 09:07:22 +01:00
parent 04fe0efc67
commit 8b2e5f2130
569 changed files with 62491 additions and 5875 deletions

View file

@ -58,6 +58,7 @@ set(libobs-opengl_SOURCES
gl-stagesurf.c
gl-subsystem.c
gl-texture2d.c
gl-texture3d.c
gl-texturecube.c
gl-vertexbuffer.c
gl-zstencil.c)

View file

@ -25,13 +25,16 @@
struct gl_windowinfo {
NSView *view;
NSOpenGLContext *context;
gs_texture_t *texture;
GLuint fbo;
};
struct gl_platform {
NSOpenGLContext *context;
};
static NSOpenGLContext *gl_context_create(void)
static NSOpenGLContext *gl_context_create(NSOpenGLContext *share)
{
unsigned attrib_count = 0;
@ -62,7 +65,8 @@ static NSOpenGLContext *gl_context_create(void)
}
NSOpenGLContext *context;
context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil];
context = [[NSOpenGLContext alloc] initWithFormat:pf
shareContext:share];
[pf release];
if (!context) {
blog(LOG_ERROR, "Failed to create context");
@ -76,28 +80,29 @@ static NSOpenGLContext *gl_context_create(void)
struct gl_platform *gl_platform_create(gs_device_t *device, uint32_t adapter)
{
struct gl_platform *plat = bzalloc(sizeof(struct gl_platform));
GLint interval = 0;
plat->context = gl_context_create();
if (!plat->context)
goto fail;
[plat->context makeCurrentContext];
[plat->context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
if (!gladLoadGL())
goto fail;
return plat;
fail:
blog(LOG_ERROR, "gl_platform_create failed");
gl_platform_destroy(plat);
UNUSED_PARAMETER(device);
UNUSED_PARAMETER(adapter);
return NULL;
NSOpenGLContext *context = gl_context_create(nil);
if (!context) {
blog(LOG_ERROR, "gl_context_create failed");
return NULL;
}
[context makeCurrentContext];
GLint interval = 0;
[context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
const bool success = gladLoadGL() != 0;
if (!success) {
blog(LOG_ERROR, "gladLoadGL failed");
[context release];
return NULL;
}
struct gl_platform *plat = bzalloc(sizeof(struct gl_platform));
plat->context = context;
return plat;
}
void gl_platform_destroy(struct gl_platform *platform)
@ -113,14 +118,72 @@ void gl_platform_destroy(struct gl_platform *platform)
bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
{
UNUSED_PARAMETER(swap);
NSOpenGLContext *parent = swap->device->plat->context;
NSOpenGLContext *context = gl_context_create(parent);
bool success = context != nil;
if (success) {
CGLContextObj parent_obj = [parent CGLContextObj];
CGLLockContext(parent_obj);
return true;
[parent makeCurrentContext];
struct gs_init_data *init_data = &swap->info;
swap->wi->texture = device_texture_create(
swap->device, init_data->cx, init_data->cy,
init_data->format, 1, NULL, GS_RENDER_TARGET);
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLContextObj context_obj = [context CGLContextObj];
CGLLockContext(context_obj);
[context makeCurrentContext];
[context setView:swap->wi->view];
GLint interval = 0;
[context setValues:&interval
forParameter:NSOpenGLCPSwapInterval];
gl_gen_framebuffers(1, &swap->wi->fbo);
gl_bind_framebuffer(GL_FRAMEBUFFER, swap->wi->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
swap->wi->texture->texture, 0);
gl_success("glFrameBufferTexture2D");
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext(context_obj);
CGLUnlockContext(parent_obj);
swap->wi->context = context;
}
return success;
}
void gl_platform_cleanup_swapchain(struct gs_swap_chain *swap)
{
UNUSED_PARAMETER(swap);
NSOpenGLContext *parent = swap->device->plat->context;
CGLContextObj parent_obj = [parent CGLContextObj];
CGLLockContext(parent_obj);
NSOpenGLContext *context = swap->wi->context;
CGLContextObj context_obj = [context CGLContextObj];
CGLLockContext(context_obj);
[context makeCurrentContext];
gl_delete_framebuffers(1, &swap->wi->fbo);
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext(context_obj);
[parent makeCurrentContext];
gs_texture_destroy(swap->wi->texture);
glFlush();
[NSOpenGLContext clearCurrentContext];
swap->wi->context = nil;
CGLUnlockContext(parent_obj);
}
struct gl_windowinfo *gl_windowinfo_create(const struct gs_init_data *info)
@ -150,19 +213,62 @@ void gl_windowinfo_destroy(struct gl_windowinfo *wi)
void gl_update(gs_device_t *device)
{
[device->plat->context update];
gs_swapchain_t *swap = device->cur_swap;
NSOpenGLContext *parent = device->plat->context;
NSOpenGLContext *context = swap->wi->context;
dispatch_async(dispatch_get_main_queue(), ^() {
CGLContextObj parent_obj = [parent CGLContextObj];
CGLLockContext(parent_obj);
CGLContextObj context_obj = [context CGLContextObj];
CGLLockContext(context_obj);
[context makeCurrentContext];
[context update];
struct gs_init_data *info = &swap->info;
gs_texture_t *previous = swap->wi->texture;
swap->wi->texture = device_texture_create(device, info->cx,
info->cy,
info->format, 1, NULL,
GS_RENDER_TARGET);
gl_bind_framebuffer(GL_FRAMEBUFFER, swap->wi->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
swap->wi->texture->texture, 0);
gl_success("glFrameBufferTexture2D");
gs_texture_destroy(previous);
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext(context_obj);
CGLUnlockContext(parent_obj);
});
}
void gl_clear_context(gs_device_t *device)
{
UNUSED_PARAMETER(device);
[NSOpenGLContext clearCurrentContext];
}
void device_enter_context(gs_device_t *device)
{
CGLLockContext([device->plat->context CGLContextObj]);
[device->plat->context makeCurrentContext];
}
void device_leave_context(gs_device_t *device)
{
UNUSED_PARAMETER(device);
glFlush();
[NSOpenGLContext clearCurrentContext];
device->cur_render_target = NULL;
device->cur_zstencil_buffer = NULL;
device->cur_swap = NULL;
device->cur_fbo = NULL;
CGLUnlockContext([device->plat->context CGLContextObj]);
}
void *device_get_device_obj(gs_device_t *device)
@ -177,15 +283,35 @@ void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap)
device->cur_swap = swap;
if (swap) {
[device->plat->context setView:swap->wi->view];
} else {
[device->plat->context clearDrawable];
device_set_render_target(device, swap->wi->texture, NULL);
}
}
void device_present(gs_device_t *device)
{
[device->plat->context flushBuffer];
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext([device->plat->context CGLContextObj]);
CGLLockContext([device->cur_swap->wi->context CGLContextObj]);
[device->cur_swap->wi->context makeCurrentContext];
gl_bind_framebuffer(GL_READ_FRAMEBUFFER, device->cur_swap->wi->fbo);
gl_bind_framebuffer(GL_DRAW_FRAMEBUFFER, 0);
const uint32_t width = device->cur_swap->info.cx;
const uint32_t height = device->cur_swap->info.cy;
glBlitFramebuffer(0, 0, width, height, 0, height, width, 0,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
[device->cur_swap->wi->context flushBuffer];
glFlush();
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext([device->cur_swap->wi->context CGLContextObj]);
CGLLockContext([device->plat->context CGLContextObj]);
[device->plat->context makeCurrentContext];
}
void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,

View file

@ -45,13 +45,10 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels,
data++;
size /= 4;
width /= 2;
height /= 2;
if (width == 0)
width = 1;
if (height == 0)
height = 1;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
}
if (data)

View file

@ -149,12 +149,24 @@ static inline bool gl_bind_renderbuffer(GLenum target, GLuint buffer)
return gl_success("glBindRendebuffer");
}
static inline bool gl_gen_framebuffers(GLsizei num_arrays, GLuint *arrays)
{
glGenFramebuffers(num_arrays, arrays);
return gl_success("glGenFramebuffers");
}
static inline bool gl_bind_framebuffer(GLenum target, GLuint buffer)
{
glBindFramebuffer(target, buffer);
return gl_success("glBindFramebuffer");
}
static inline void gl_delete_framebuffers(GLsizei num_arrays, GLuint *arrays)
{
glDeleteFramebuffers(num_arrays, arrays);
gl_success("glDeleteFramebuffers");
}
static inline bool gl_tex_param_f(GLenum target, GLenum param, GLfloat val)
{
glTexParameterf(target, param, val);

View file

@ -692,7 +692,7 @@ static bool gl_shader_buildstring(struct gl_shader_parser *glsp)
return false;
}
dstr_copy(&glsp->gl_string, "#version 150\n\n");
dstr_copy(&glsp->gl_string, "#version 330\n\n");
dstr_cat(&glsp->gl_string, "const bool obs_glsl_compile = true;\n\n");
gl_write_params(glsp);
gl_write_inputs(glsp, main_func);

View file

@ -130,23 +130,15 @@ static void gl_enable_debug() {}
static bool gl_init_extensions(struct gs_device *device)
{
if (!GLAD_GL_VERSION_2_1) {
blog(LOG_ERROR, "obs-studio requires OpenGL version 2.1 or "
"higher.");
if (!GLAD_GL_VERSION_3_3) {
blog(LOG_ERROR,
"obs-studio requires OpenGL version 3.3 or higher.");
return false;
}
gl_enable_debug();
if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ARB_framebuffer_object) {
blog(LOG_ERROR, "OpenGL extension ARB_framebuffer_object "
"is required.");
return false;
}
if (GLAD_GL_VERSION_3_2 || GLAD_GL_ARB_seamless_cube_map) {
gl_enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
gl_enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
if (GLAD_GL_VERSION_4_3 || GLAD_GL_ARB_copy_image)
device->copy_type = COPY_TYPE_ARB;
@ -182,8 +174,11 @@ void convert_sampler_info(struct gs_sampler_state *sampler,
sampler->max_anisotropy = info->max_anisotropy;
max_anisotropy_max = 1;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy_max);
gl_success("glGetIntegerv(GL_MAX_TEXTURE_ANISOTROPY_MAX)");
if (GLAD_GL_EXT_texture_filter_anisotropic) {
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
&max_anisotropy_max);
gl_success("glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)");
}
if (1 <= sampler->max_anisotropy &&
sampler->max_anisotropy <= max_anisotropy_max)
@ -250,7 +245,7 @@ int device_create(gs_device_t **p_device, uint32_t adapter)
gl_enable(GL_CULL_FACE);
gl_gen_vertex_arrays(1, &device->empty_vao);
device_leave_context(device);
gl_clear_context(device);
device->cur_swap = NULL;
#ifdef _WIN32
@ -354,24 +349,6 @@ uint32_t device_get_height(const gs_device_t *device)
}
}
gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width,
uint32_t height, uint32_t depth,
enum gs_color_format color_format,
uint32_t levels, const uint8_t **data,
uint32_t flags)
{
/* TODO */
UNUSED_PARAMETER(device);
UNUSED_PARAMETER(width);
UNUSED_PARAMETER(height);
UNUSED_PARAMETER(depth);
UNUSED_PARAMETER(color_format);
UNUSED_PARAMETER(levels);
UNUSED_PARAMETER(data);
UNUSED_PARAMETER(flags);
return NULL;
}
gs_samplerstate_t *
device_samplerstate_create(gs_device_t *device,
const struct gs_sampler_info *info)
@ -475,9 +452,12 @@ static bool load_texture_sampler(gs_texture_t *tex, gs_samplerstate_t *ss)
success = false;
if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_WRAP_R, ss->address_w))
success = false;
if (!gl_tex_param_i(tex->gl_target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
ss->max_anisotropy))
success = false;
if (GLAD_GL_EXT_texture_filter_anisotropic) {
if (!gl_tex_param_i(tex->gl_target,
GL_TEXTURE_MAX_ANISOTROPY_EXT,
ss->max_anisotropy))
success = false;
}
apply_swizzle(tex);
@ -929,6 +909,12 @@ void device_copy_texture(gs_device_t *device, gs_texture_t *dst,
device_copy_texture_region(device, dst, 0, 0, src, 0, 0, 0, 0);
}
void device_begin_frame(gs_device_t *device)
{
/* does nothing */
UNUSED_PARAMETER(device);
}
void device_begin_scene(gs_device_t *device)
{
clear_textures(device);
@ -1421,12 +1407,6 @@ void gs_swapchain_destroy(gs_swapchain_t *swapchain)
bfree(swapchain);
}
void gs_voltexture_destroy(gs_texture_t *voltex)
{
/* TODO */
UNUSED_PARAMETER(voltex);
}
uint32_t gs_voltexture_get_width(const gs_texture_t *voltex)
{
/* TODO */

View file

@ -144,17 +144,17 @@ static inline GLenum get_gl_format_type(enum gs_color_format format)
case GS_R16:
return GL_UNSIGNED_SHORT;
case GS_RGBA16F:
return GL_UNSIGNED_SHORT;
return GL_HALF_FLOAT;
case GS_RGBA32F:
return GL_FLOAT;
case GS_RG16F:
return GL_UNSIGNED_SHORT;
return GL_HALF_FLOAT;
case GS_RG32F:
return GL_FLOAT;
case GS_R8G8:
return GL_UNSIGNED_BYTE;
case GS_R16F:
return GL_UNSIGNED_SHORT;
return GL_HALF_FLOAT;
case GS_R32F:
return GL_FLOAT;
case GS_DXT1:
@ -527,6 +527,16 @@ struct gs_texture_2d {
GLuint unpack_buffer;
};
struct gs_texture_3d {
struct gs_texture base;
uint32_t width;
uint32_t height;
uint32_t depth;
bool gen_mipmaps;
GLuint unpack_buffer;
};
struct gs_texture_cube {
struct gs_texture base;
@ -617,6 +627,7 @@ extern struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width,
uint32_t height);
extern void gl_update(gs_device_t *device);
extern void gl_clear_context(gs_device_t *device);
extern struct gl_platform *gl_platform_create(gs_device_t *device,
uint32_t adapter);

View file

@ -26,7 +26,7 @@ static bool upload_texture_2d(struct gs_texture_2d *tex, const uint8_t **data)
bool success;
if (!num_levels)
num_levels = gs_get_total_levels(tex->width, tex->height);
num_levels = gs_get_total_levels(tex->width, tex->height, 1);
if (!gl_bind_texture(GL_TEXTURE_2D, tex->base.texture))
return false;
@ -145,18 +145,25 @@ static inline bool is_texture_2d(const gs_texture_t *tex, const char *func)
void gs_texture_destroy(gs_texture_t *tex)
{
struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex;
if (!tex)
return;
if (!is_texture_2d(tex, "gs_texture_destroy"))
return;
if (tex->cur_sampler)
gs_samplerstate_destroy(tex->cur_sampler);
if (!tex->is_dummy && tex->is_dynamic && tex2d->unpack_buffer)
gl_delete_buffers(1, &tex2d->unpack_buffer);
if (!tex->is_dummy && tex->is_dynamic) {
if (tex->type == GS_TEXTURE_2D) {
struct gs_texture_2d *tex2d =
(struct gs_texture_2d *)tex;
if (tex2d->unpack_buffer)
gl_delete_buffers(1, &tex2d->unpack_buffer);
} else if (tex->type == GS_TEXTURE_3D) {
struct gs_texture_3d *tex3d =
(struct gs_texture_3d *)tex;
if (tex3d->unpack_buffer)
gl_delete_buffers(1, &tex3d->unpack_buffer);
}
}
if (tex->texture)
gl_delete_textures(1, &tex->texture);
@ -253,19 +260,22 @@ failed:
bool gs_texture_is_rect(const gs_texture_t *tex)
{
const struct gs_texture_2d *tex2d = (const struct gs_texture_2d *)tex;
if (!is_texture_2d(tex, "gs_texture_unmap")) {
if (tex->type == GS_TEXTURE_3D)
return false;
if (!is_texture_2d(tex, "gs_texture_is_rect")) {
blog(LOG_ERROR, "gs_texture_is_rect (GL) failed");
return false;
}
const struct gs_texture_2d *tex2d = (const struct gs_texture_2d *)tex;
return tex2d->base.gl_target == GL_TEXTURE_RECTANGLE;
}
void *gs_texture_get_obj(gs_texture_t *tex)
{
struct gs_texture_2d *tex2d = (struct gs_texture_2d *)tex;
if (!is_texture_2d(tex, "gs_texture_unmap")) {
if (!is_texture_2d(tex, "gs_texture_get_obj")) {
blog(LOG_ERROR, "gs_texture_get_obj (GL) failed");
return NULL;
}

View file

@ -0,0 +1,186 @@
/******************************************************************************
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "gl-subsystem.h"
static bool gl_init_volume(GLenum type, uint32_t num_levels, GLenum format,
GLint internal_format, bool compressed,
uint32_t width, uint32_t height, uint32_t depth,
const uint8_t *const **p_data)
{
bool success = true;
const uint8_t *const *data = p_data ? *p_data : NULL;
uint32_t i;
const uint32_t bpp = gs_get_format_bpp(format);
for (i = 0; i < num_levels; i++) {
if (compressed) {
uint32_t mip_size = width * height * depth * bpp / 8;
glCompressedTexImage3D(GL_TEXTURE_3D, i,
internal_format, width, height,
depth, 0, mip_size,
data ? *data : NULL);
if (!gl_success("glCompressedTexImage3D"))
success = false;
} else {
glTexImage3D(GL_TEXTURE_3D, i, internal_format, width,
height, depth, 0, format, type,
data ? *data : NULL);
if (!gl_success("glTexImage3D"))
success = false;
}
if (data)
data++;
if (width > 1)
width /= 2;
if (height > 1)
height /= 2;
if (depth > 1)
depth /= 2;
}
if (data)
*p_data = data;
return success;
}
static bool upload_texture_3d(struct gs_texture_3d *tex,
const uint8_t *const *data)
{
uint32_t num_levels = tex->base.levels;
bool compressed = gs_is_compressed_format(tex->base.format);
bool success;
if (!num_levels)
num_levels = gs_get_total_levels(tex->width, tex->height,
tex->depth);
if (!gl_bind_texture(GL_TEXTURE_3D, tex->base.texture))
return false;
success = gl_init_volume(tex->base.gl_type, num_levels,
tex->base.gl_format,
tex->base.gl_internal_format, compressed,
tex->width, tex->height, tex->depth, &data);
if (!gl_tex_param_i(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,
num_levels - 1))
success = false;
if (!gl_bind_texture(GL_TEXTURE_3D, 0))
success = false;
return success;
}
static bool create_pixel_unpack_buffer(struct gs_texture_3d *tex)
{
GLsizeiptr size;
bool success = true;
if (!gl_gen_buffers(1, &tex->unpack_buffer))
return false;
if (!gl_bind_buffer(GL_PIXEL_UNPACK_BUFFER, tex->unpack_buffer))
return false;
size = tex->width * gs_get_format_bpp(tex->base.format);
if (!gs_is_compressed_format(tex->base.format)) {
size /= 8;
size = (size + 3) & 0xFFFFFFFC;
size *= tex->height;
size *= tex->depth;
} else {
size *= tex->height;
size *= tex->depth;
size /= 8;
}
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, 0, GL_DYNAMIC_DRAW);
if (!gl_success("glBufferData"))
success = false;
if (!gl_bind_buffer(GL_PIXEL_UNPACK_BUFFER, 0))
success = false;
return success;
}
gs_texture_t *device_voltexture_create(gs_device_t *device, uint32_t width,
uint32_t height, uint32_t depth,
enum gs_color_format color_format,
uint32_t levels,
const uint8_t *const *data,
uint32_t flags)
{
struct gs_texture_3d *tex = bzalloc(sizeof(struct gs_texture_3d));
tex->base.device = device;
tex->base.type = GS_TEXTURE_3D;
tex->base.format = color_format;
tex->base.levels = levels;
tex->base.gl_format = convert_gs_format(color_format);
tex->base.gl_internal_format = convert_gs_internal_format(color_format);
tex->base.gl_type = get_gl_format_type(color_format);
tex->base.gl_target = GL_TEXTURE_3D;
tex->base.is_dynamic = (flags & GS_DYNAMIC) != 0;
tex->base.is_render_target = false;
tex->base.is_dummy = (flags & GS_GL_DUMMYTEX) != 0;
tex->base.gen_mipmaps = (flags & GS_BUILD_MIPMAPS) != 0;
tex->width = width;
tex->height = height;
tex->depth = depth;
if (!gl_gen_textures(1, &tex->base.texture))
goto fail;
if (!tex->base.is_dummy) {
if (tex->base.is_dynamic && !create_pixel_unpack_buffer(tex))
goto fail;
if (!upload_texture_3d(tex, data))
goto fail;
} else {
if (!gl_bind_texture(GL_TEXTURE_3D, tex->base.texture))
goto fail;
bool compressed = gs_is_compressed_format(tex->base.format);
bool did_init = gl_init_volume(tex->base.gl_type, 1,
tex->base.gl_format,
tex->base.gl_internal_format,
compressed, tex->width,
tex->height, tex->depth, NULL);
did_init =
gl_tex_param_i(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
bool did_unbind = gl_bind_texture(GL_TEXTURE_3D, 0);
if (!did_init || !did_unbind)
goto fail;
}
return (gs_texture_t *)tex;
fail:
gs_texture_destroy((gs_texture_t *)tex);
blog(LOG_ERROR, "device_voltexture_create (GL) failed");
return NULL;
}
void gs_voltexture_destroy(gs_texture_t *voltex)
{
gs_texture_destroy(voltex);
}

View file

@ -29,7 +29,7 @@ static inline bool upload_texture_cube(struct gs_texture_cube *tex,
uint32_t i;
if (!num_levels)
num_levels = gs_get_total_levels(tex->size, tex->size);
num_levels = gs_get_total_levels(tex->size, tex->size, 1);
for (i = 0; i < 6; i++) {
GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;

View file

@ -41,6 +41,7 @@ static inline int get_color_format_bits(enum gs_color_format format)
{
switch ((uint32_t)format) {
case GS_RGBA:
case GS_BGRA:
return 32;
default:
return 0;
@ -154,35 +155,37 @@ static inline HGLRC gl_init_basic_context(HDC hdc)
return hglrc;
}
static const int attribs[] = {
#ifdef _DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
#endif
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0, 0};
static inline HGLRC gl_init_context(HDC hdc)
{
static const int attribs[] = {
#ifdef _DEBUG
if (GLAD_WGL_ARB_create_context) {
HGLRC hglrc = wglCreateContextAttribsARB(hdc, 0, attribs);
if (!hglrc) {
blog(LOG_ERROR,
"wglCreateContextAttribsARB failed, "
"%lu",
GetLastError());
return NULL;
}
if (!wgl_make_current(hdc, hglrc)) {
wglDeleteContext(hglrc);
return NULL;
}
return hglrc;
}
WGL_CONTEXT_FLAGS_ARB,
WGL_CONTEXT_DEBUG_BIT_ARB,
#endif
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_MAJOR_VERSION_ARB,
3,
WGL_CONTEXT_MINOR_VERSION_ARB,
3,
0,
0};
return gl_init_basic_context(hdc);
HGLRC hglrc = wglCreateContextAttribsARB(hdc, 0, attribs);
if (!hglrc) {
blog(LOG_ERROR,
"wglCreateContextAttribsARB failed, "
"%lu",
GetLastError());
return NULL;
}
if (!wgl_make_current(hdc, hglrc)) {
wglDeleteContext(hglrc);
return NULL;
}
return hglrc;
}
static bool gl_dummy_context_init(struct dummy_context *dummy)
@ -412,6 +415,12 @@ void gl_update(gs_device_t *device)
UNUSED_PARAMETER(device);
}
void gl_clear_context(gs_device_t *device)
{
UNUSED_PARAMETER(device);
wglMakeCurrent(NULL, NULL);
}
static void init_dummy_swap_info(struct gs_init_data *info)
{
info->format = GS_RGBA;
@ -538,8 +547,8 @@ void device_enter_context(gs_device_t *device)
void device_leave_context(gs_device_t *device)
{
wglMakeCurrent(NULL, NULL);
UNUSED_PARAMETER(device);
wglMakeCurrent(NULL, NULL);
}
void *device_get_device_obj(gs_device_t *device)

View file

@ -50,7 +50,7 @@ static const int ctx_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB,
3,
GLX_CONTEXT_MINOR_VERSION_ARB,
2,
3,
None,
};
@ -95,53 +95,6 @@ struct gl_platform {
GLXPbuffer pbuffer;
};
static void print_info_stuff(const struct gs_init_data *info)
{
blog(LOG_INFO,
"X and Y: %i %i\n"
"Backbuffers: %i\n"
"Color Format: %i\n"
"ZStencil Format: %i\n"
"Adapter: %i\n",
info->cx, info->cy, info->num_backbuffers, info->format,
info->zsformat, info->adapter);
}
/* The following utility functions are copied verbatim from WGL code.
* GLX and WGL are more similar than most people realize. */
/* For now, only support basic 32bit formats for graphics output. */
static inline int get_color_format_bits(enum gs_color_format format)
{
switch ((uint32_t)format) {
case GS_RGBA:
return 32;
default:
return 0;
}
}
static inline int get_depth_format_bits(enum gs_zstencil_format zsformat)
{
switch ((uint32_t)zsformat) {
case GS_Z16:
return 16;
case GS_Z24_S8:
return 24;
default:
return 0;
}
}
static inline int get_stencil_format_bits(enum gs_zstencil_format zsformat)
{
switch ((uint32_t)zsformat) {
case GS_Z24_S8:
return 8;
default:
return 0;
}
}
/*
* Since we cannot take advantage of the asynchronous nature of xcb,
* all of the helper functions are synchronous but thread-safe.
@ -277,7 +230,6 @@ gl_windowinfo_create(const struct gs_init_data *info)
extern void gl_windowinfo_destroy(struct gl_windowinfo *info)
{
UNUSED_PARAMETER(info);
bfree(info);
}
@ -532,6 +484,15 @@ extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
free(geometry);
}
extern void gl_clear_context(gs_device_t *device)
{
Display *display = device->plat->display;
if (!glXMakeContextCurrent(display, None, None, NULL)) {
blog(LOG_ERROR, "Failed to reset current context.");
}
}
extern void gl_update(gs_device_t *device)
{
Display *display = device->plat->display;