diff --git a/libobs-d3d11/d3d11-exports.h b/libobs-d3d11/d3d11-exports.h index 8993728a31c572f3242de181e981a9fd6b61fffe..865be264619381c658bc399e1f8c7de860cb42cf 100644 --- a/libobs-d3d11/d3d11-exports.h +++ b/libobs-d3d11/d3d11-exports.h @@ -97,8 +97,8 @@ EXPORT void device_enable_blending(device_t device, bool enable); EXPORT void device_enable_depthtest(device_t device, bool enable); EXPORT void device_enable_stenciltest(device_t device, bool enable); EXPORT void device_enable_stencilwrite(device_t device, bool enable); -EXPORT void device_enable_color(device_t device, bool red, bool blue, - bool green, bool alpha); +EXPORT void device_enable_color(device_t device, bool red, bool green, + bool blue, bool alpha); EXPORT void device_blendfunction(device_t device, enum gs_blend_type src, enum gs_blend_type dest); EXPORT void device_depthfunction(device_t device, enum gs_depth_test test); @@ -125,7 +125,6 @@ EXPORT void device_frustum(device_t device, float left, float right, float top, float bottom, float znear, float zfar); EXPORT void device_perspective(device_t device, float fovy, float aspect, float znear, float zfar); -EXPORT void device_set_view_matrix(device_t device, struct matrix3 *mat); EXPORT void device_projection_push(device_t device); EXPORT void device_projection_pop(device_t device); diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index abe9ca6c67804c18148f0b9f66c742440e94fdd6..bce6160b09288af3f531d834ae982c2882a27886 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -1130,8 +1130,8 @@ void device_enable_stencilwrite(device_t device, bool enable) device->zstencilStateChanged = true; } -void device_enable_color(device_t device, bool red, bool blue, - bool green, bool alpha) +void device_enable_color(device_t device, bool red, bool green, + bool blue, bool alpha) { if (device->blendState.redEnabled == red && device->blendState.greenEnabled == green && diff --git a/libobs-opengl/gl-exports.h b/libobs-opengl/gl-exports.h index f27608f734680e87cb6a5823038e8ee0acf84f25..27242217c1ec0c860e62fcb95567edf9ac10bee5 100644 --- a/libobs-opengl/gl-exports.h +++ b/libobs-opengl/gl-exports.h @@ -91,8 +91,8 @@ EXPORT void device_enable_blending(device_t device, bool enable); EXPORT void device_enable_depthtest(device_t device, bool enable); EXPORT void device_enable_stenciltest(device_t device, bool enable); EXPORT void device_enable_stencilwrite(device_t device, bool enable); -EXPORT void device_enable_color(device_t device, bool red, bool blue, - bool green, bool alpha); +EXPORT void device_enable_color(device_t device, bool red, bool green, + bool blue, bool alpha); EXPORT void device_blendfunction(device_t device, enum gs_blend_type src, enum gs_blend_type dest); EXPORT void device_depthfunction(device_t device, enum gs_depth_test test); @@ -119,7 +119,6 @@ EXPORT void device_frustum(device_t device, float left, float right, float top, float bottom, float znear, float zfar); EXPORT void device_perspective(device_t device, float fovy, float aspect, float znear, float zfar); -EXPORT void device_set_view_matrix(device_t device, struct matrix3 *mat); EXPORT void device_projection_push(device_t device); EXPORT void device_projection_pop(device_t device); diff --git a/libobs-opengl/gl-helpers.h b/libobs-opengl/gl-helpers.h index 7517e968e0d0aab7bd0555399d7ef384b848960c..1d7f8486066540bf52763ce840c9172d80d39cf3 100644 --- a/libobs-opengl/gl-helpers.h +++ b/libobs-opengl/gl-helpers.h @@ -96,12 +96,24 @@ static inline bool gl_tex_param_i(GLenum target, GLenum param, GLint val) return gl_success("glTexParameteri"); } -static inline bool gl_active_texture(GLenum texture) +static inline bool gl_active_texture(GLenum texture_id) { - glActiveTexture(texture); + glActiveTexture(texture_id); return gl_success("glActiveTexture"); } +static inline bool gl_enable(GLenum capability) +{ + glEnable(capability); + return gl_success("glEnable"); +} + +static inline bool gl_disable(GLenum capability) +{ + glDisable(capability); + return gl_success("glDisable"); +} + extern bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, GLenum format, GLint internal_format, bool compressed, uint32_t width, uint32_t height, uint32_t size, void ***p_data); diff --git a/libobs-opengl/gl-indexbuffer.c b/libobs-opengl/gl-indexbuffer.c index 6e2fa1e017488f07847eb832ec5f1cd58ca19438..6a3d8cc551f8222a84a9ee14e372ec5f31a701e1 100644 --- a/libobs-opengl/gl-indexbuffer.c +++ b/libobs-opengl/gl-indexbuffer.c @@ -45,6 +45,7 @@ indexbuffer_t device_create_indexbuffer(device_t device, ib->data = indices; ib->dynamic = flags & GS_DYNAMIC; ib->num = num; + ib->width = width; ib->size = width * num; ib->type = type; ib->gl_type = type == GS_UNSIGNED_LONG ? GL_UNSIGNED_INT : diff --git a/libobs-opengl/gl-shader.c b/libobs-opengl/gl-shader.c index 199a18c6f48088300135a9be59823e852dabc320..bc098d41974f0c9d12711c5b62285289d1c3bc46 100644 --- a/libobs-opengl/gl-shader.c +++ b/libobs-opengl/gl-shader.c @@ -77,6 +77,9 @@ static bool gl_add_param(struct gs_shader *shader, struct shader_var *var, if (!gl_success("glGetUniformLocation")) return false; + if (param.type == SHADER_PARAM_TEXTURE) + glUniform1i(param.param, param.texture_id); + return true; } @@ -155,6 +158,12 @@ static inline bool gl_add_attrib(struct gs_shader *shader, if (attrib.attrib == -1) return false; + if (attrib.type == ATTRIB_TARGET) { + glBindFragDataLocation(shader->program, 0, pa->name.array); + if (!gl_success("glBindFragDataLocation")) + return false; + } + da_push_back(shader->attribs, &attrib); return true; } diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index 5d434ee2730cc7edd39d6ca25bee052b34089dd1..13af947e7813e220de071a24b203a239d40a31b8 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -17,6 +17,18 @@ #include "gl-subsystem.h" +static void clear_textures(struct gs_device *device) +{ + GLenum i; + for (i = 0; i < GS_MAX_TEXTURES; i++) { + if (device->cur_textures[i]) { + gl_active_texture(GL_TEXTURE0 + i); + gl_bind_texture(device->cur_textures[i]->gl_target, 0); + device->cur_textures[i] = NULL; + } + } +} + void convert_sampler_info(struct gs_sampler_state *sampler, struct gs_sampler_info *info) { @@ -45,6 +57,10 @@ device_t device_create(struct gs_init_data *info) if (!gl_success("glBindProgramPipeline")) goto fail; +#ifdef _DEBUG + gl_enable(GL_DEBUG_OUTPUT); +#endif + return device; fail: @@ -63,6 +79,7 @@ void device_destroy(device_t device) if (device->pipeline) glDeleteProgramPipelines(1, &device->pipeline); + da_free(device->proj_stack); da_free(device->fbos); gl_platform_destroy(device->plat); bfree(device); @@ -191,13 +208,16 @@ void device_load_texture(device_t device, texture_t tex, int unit) { struct shader_param *param; struct gs_sampler_state *sampler; + struct gs_texture *cur_tex = device->cur_textures[unit]; /* need a pixel shader to properly bind textures */ if (!device->cur_pixel_shader) tex = NULL; - if (device->cur_textures[unit] == tex) + if (cur_tex == tex) return; + if (cur_tex && cur_tex->gl_target != tex->gl_target) + gl_bind_texture(cur_tex->gl_target, 0); device->cur_textures[unit] = tex; param = get_texture_param(device, unit); @@ -323,6 +343,7 @@ void device_load_pixelshader(device_t device, shader_t pixelshader) if (!gl_success("glUseProgramStages")) goto fail; + clear_textures(device); return; fail: @@ -581,144 +602,290 @@ fail: void device_beginscene(device_t device) { + clear_textures(device); } -void device_draw(device_t device, enum gs_draw_mode draw_mode, - uint32_t start_vert, uint32_t num_verts) +static inline bool can_render(device_t device) { + if (!device->cur_vertex_buffer) { + blog(LOG_ERROR, "No vertex buffer specified"); + return false; + } + + if (!device->cur_vertex_buffer) { + blog(LOG_ERROR, "No vertex buffer specified"); + return false; + } + + if (!device->cur_vertex_buffer) { + blog(LOG_ERROR, "No vertex buffer specified"); + return false; + } + + return true; } -void device_endscene(device_t device) +void device_draw(device_t device, enum gs_draw_mode draw_mode, + uint32_t start_vert, uint32_t num_verts) { + struct gs_index_buffer *ib = device->cur_index_buffer; + GLenum topology = convert_gs_topology(draw_mode); + + if (!can_render(device)) + goto fail; + + if (ib) { + glDrawElements(topology, num_verts, ib->gl_type, + (const GLvoid*)(start_vert * ib->width)); + if (!gl_success("glDrawElements")) + goto fail; + + } else { + glDrawArrays(topology, start_vert, num_verts); + if (!gl_success("glDrawArrays")) + goto fail; + } + + return; + +fail: + blog(LOG_ERROR, "device_draw (GL) failed"); } -void device_load_swapchain(device_t device, swapchain_t swapchain) +void device_endscene(device_t device) { + /* does nothing */ } void device_clear(device_t device, uint32_t clear_flags, struct vec4 *color, float depth, uint8_t stencil) { -} + GLbitfield gl_flags = 0; -void device_present(device_t device) -{ + if (clear_flags & GS_CLEAR_COLOR) { + glClearColor(color->x, color->y, color->x, color->w); + gl_flags |= GL_COLOR_BUFFER_BIT; + } + + if (clear_flags & GS_CLEAR_DEPTH) { + glClearDepth(depth); + gl_flags |= GL_DEPTH_BUFFER_BIT; + } + + if (clear_flags & GS_CLEAR_STENCIL) { + glClearStencil(stencil); + gl_flags |= GL_STENCIL_BUFFER_BIT; + } + + glClear(clear_flags); + if (!gl_success("glClear")) + blog(LOG_ERROR, "device_clear (GL) failed"); } void device_setcullmode(device_t device, enum gs_cull_mode mode) { + if (device->cur_cull_mode == mode) + return; + + if (device->cur_cull_mode == GS_NEITHER) + gl_enable(GL_CULL_FACE); + + device->cur_cull_mode = mode; + if (mode == GS_BACK) + glCullFace(GL_BACK); + else if (mode == GS_FRONT) + glCullFace(GL_FRONT); + else + gl_disable(GL_CULL_FACE); } enum gs_cull_mode device_getcullmode(device_t device) { + return device->cur_cull_mode; } void device_enable_blending(device_t device, bool enable) { + if (enable) + gl_enable(GL_BLEND); + else + gl_disable(GL_BLEND); } void device_enable_depthtest(device_t device, bool enable) { + if (enable) + gl_enable(GL_DEPTH_TEST); + else + gl_disable(GL_DEPTH_TEST); } void device_enable_stenciltest(device_t device, bool enable) { + if (enable) + gl_enable(GL_STENCIL_TEST); + else + gl_disable(GL_STENCIL_TEST); } void device_enable_stencilwrite(device_t device, bool enable) { + if (enable) + glStencilMask(0xFFFFFFFF); + else + glStencilMask(0); } -void device_enable_color(device_t device, bool red, bool blue, - bool green, bool alpha) +void device_enable_color(device_t device, bool red, bool green, + bool blue, bool alpha) { + glColorMask(red, green, blue, alpha); } void device_blendfunction(device_t device, enum gs_blend_type src, enum gs_blend_type dest) { + GLenum gl_src = convert_gs_blend_type(src); + GLenum gl_dst = convert_gs_blend_type(dest); + + glBlendFunc(gl_src, gl_dst); + if (!gl_success("glBlendFunc")) + blog(LOG_ERROR, "device_blendfunction (GL) failed"); } void device_depthfunction(device_t device, enum gs_depth_test test) { + GLenum gl_test = convert_gs_depth_test(test); + + glDepthFunc(gl_test); + if (!gl_success("glDepthFunc")) + blog(LOG_ERROR, "device_depthfunction (GL) failed"); } void device_stencilfunction(device_t device, enum gs_stencil_side side, enum gs_depth_test test) { + GLenum gl_side = convert_gs_stencil_side(side); + GLenum gl_test = convert_gs_depth_test(test); + + glStencilFuncSeparate(gl_side, gl_test, 0, 0xFFFFFFFF); + if (!gl_success("glStencilFuncSeparate")) + blog(LOG_ERROR, "device_stencilfunction (GL) failed"); } void device_stencilop(device_t device, enum gs_stencil_side side, enum gs_stencil_op fail, enum gs_stencil_op zfail, enum gs_stencil_op zpass) { + GLenum gl_side = convert_gs_stencil_side(side); + GLenum gl_fail = convert_gs_stencil_op(fail); + GLenum gl_zfail = convert_gs_stencil_op(zfail); + GLenum gl_zpass = convert_gs_stencil_op(zpass); + + glStencilOpSeparate(gl_side, gl_fail, gl_zfail, gl_zpass); + if (!gl_success("glStencilOpSeparate")) + blog(LOG_ERROR, "device_stencilop (GL) failed"); } void device_enable_fullscreen(device_t device, bool enable) { + /* TODO */ } int device_fullscreen_enabled(device_t device) { + /* TODO */ + return false; } void device_setdisplaymode(device_t device, const struct gs_display_mode *mode) { + /* TODO */ } void device_getdisplaymode(device_t device, struct gs_display_mode *mode) { + /* TODO */ } void device_setcolorramp(device_t device, float gamma, float brightness, float contrast) { + /* TODO */ } void device_setviewport(device_t device, int x, int y, int width, int height) { + glViewport(x, y, width, height); + if (!gl_success("glViewport")) + blog(LOG_ERROR, "device_setviewport (GL) failed"); + + device->cur_viewport.x = x; + device->cur_viewport.y = y; + device->cur_viewport.cx = width; + device->cur_viewport.cy = height; } void device_getviewport(device_t device, struct gs_rect *rect) { + *rect = device->cur_viewport; } void device_setscissorrect(device_t device, struct gs_rect *rect) { + glScissor(rect->x, rect->y, rect->cx, rect->cy); + if (!gl_success("glScissor")) + blog(LOG_ERROR, "device_setscissorrect (GL) failed"); } void device_ortho(device_t device, float left, float right, float top, float bottom, float znear, float zfar) { + matrix4_ortho(&device->cur_proj, left, right, top, bottom, znear, zfar); } void device_frustum(device_t device, float left, float right, float top, float bottom, float znear, float zfar) { + matrix4_frustum(&device->cur_proj, left, right, top, bottom, + znear, zfar); } void device_perspective(device_t device, float fovy, float aspect, float znear, float zfar) { -} - -void device_set_view_matrix(device_t device, struct matrix3 *mat) -{ + matrix4_perspective(&device->cur_proj, fovy, aspect, znear, zfar); } void device_projection_push(device_t device) { + da_push_back(device->proj_stack, &device->cur_proj); } void device_projection_pop(device_t device) { + struct matrix4 *end; + if (!device->proj_stack.num) + return; + + end = da_end(device->proj_stack); + device->cur_proj = *end; + da_pop_back(device->proj_stack); } void swapchain_destroy(swapchain_t swapchain) { + if (!swapchain) + return; + + if (swapchain->device->cur_swap == swapchain) + device_load_swapchain(swapchain->device, NULL); + + gl_windowinfo_destroy(swapchain->wi); + bfree(swapchain); } void volumetexture_destroy(texture_t voltex) diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 5c53db296559a8ad741fb15b18e14672e5f42249..50c3ae583601905522b3c4b7fcab24bc88719ac9 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -20,6 +20,7 @@ #include "util/darray.h" #include "graphics/graphics.h" +#include "graphics/matrix4.h" #include "glew/include/GL/glew.h" #include "gl-helpers.h" #include "gl-exports.h" @@ -116,6 +117,62 @@ static inline GLenum convert_zstencil_format(enum gs_zstencil_format format) } } +static inline GLenum convert_gs_depth_test(enum gs_depth_test test) +{ + switch (test) { + default: + case GS_NEVER: return GL_NEVER; + case GS_LESS: return GL_LESS; + case GS_LEQUAL: return GL_LEQUAL; + case GS_EQUAL: return GL_EQUAL; + case GS_GEQUAL: return GL_GEQUAL; + case GS_GREATER: return GL_GREATER; + case GS_NOTEQUAL: return GL_NOTEQUAL; + case GS_ALWAYS: return GL_ALWAYS; + } +} + +static inline GLenum convert_gs_stencil_op(enum gs_stencil_op op) +{ + switch (op) { + default: + case GS_KEEP: return GL_KEEP; + case GS_ZERO: return GL_ZERO; + case GS_REPLACE: return GL_REPLACE; + case GS_INCR: return GL_INCR; + case GS_DECR: return GL_DECR; + case GS_INVERT: return GL_INVERT; + } +} + +static inline GLenum convert_gs_stencil_side(enum gs_stencil_side side) +{ + switch (side) { + default: + case GS_STENCIL_FRONT: return GL_FRONT; + case GS_STENCIL_BACK: return GL_BACK; + case GS_STENCIL_BOTH: return GL_FRONT_AND_BACK; + } +} + +static inline GLenum convert_gs_blend_type(enum gs_blend_type type) +{ + switch (type) { + default: + case GS_BLEND_ZERO: return GL_ZERO; + case GS_BLEND_ONE: return GL_ONE; + case GS_BLEND_SRCCOLOR: return GL_SRC_COLOR; + case GS_BLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR; + case GS_BLEND_SRCALPHA: return GL_SRC_ALPHA; + case GS_BLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA; + case GS_BLEND_DSTCOLOR: return GL_DST_COLOR; + case GS_BLEND_INVDSTCOLOR: return GL_ONE_MINUS_DST_COLOR; + case GS_BLEND_DSTALPHA: return GL_DST_ALPHA; + case GS_BLEND_INVDSTALPHA: return GL_ONE_MINUS_DST_ALPHA; + case GS_BLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE; + } +} + static inline GLenum convert_shader_type(enum shader_type type) { switch (type) { @@ -181,6 +238,18 @@ static inline GLint convert_address_mode(enum gs_address_mode mode) } } +static inline GLenum convert_gs_topology(enum gs_draw_mode mode) +{ + switch (mode) { + default: + case GS_POINTS: return GL_POINTS; + case GS_LINES: return GL_LINES; + case GS_LINESTRIP: return GL_LINE_STRIP; + case GS_TRIS: return GL_TRIANGLES; + case GS_TRISTRIP: return GL_TRIANGLE_STRIP; + } +} + extern void convert_sampler_info(struct gs_sampler_state *sampler, struct gs_sampler_info *info); @@ -274,6 +343,7 @@ struct gs_index_buffer { device_t device; void *data; size_t num; + size_t width; size_t size; bool dynamic; }; @@ -369,6 +439,15 @@ struct gs_device { shader_t cur_pixel_shader; swapchain_t cur_swap; + enum gs_cull_mode cur_cull_mode; + struct gs_rect cur_viewport; + + struct matrix4 cur_proj; + struct matrix4 cur_view; + struct matrix4 cur_viewproj; + + DARRAY(struct matrix4) proj_stack; + DARRAY(struct fbo_info*) fbos; struct fbo_info *cur_fbo; }; @@ -381,4 +460,6 @@ extern void gl_platform_destroy(struct gl_platform *platform); extern struct gl_windowinfo *gl_windowinfo_create(struct gs_init_data *info); extern void gl_windowinfo_destroy(struct gl_windowinfo *wi); + + #endif diff --git a/libobs-opengl/gl-windows.c b/libobs-opengl/gl-windows.c index 508fcaeb2879ee1d4a91ecd85de6133c3e062cf5..990523c3d044f311393e681011ddb70c6ad0deb5 100644 --- a/libobs-opengl/gl-windows.c +++ b/libobs-opengl/gl-windows.c @@ -427,3 +427,34 @@ void gl_windowinfo_destroy(struct gl_windowinfo *wi) bfree(wi); } } + +void device_load_swapchain(device_t device, swapchain_t swap) +{ + HDC hdc = device->plat->swap.wi->hdc; + if (device->cur_swap == swap) + return; + + device->cur_swap = swap; + + if (swap) + hdc = swap->wi->hdc; + + if (!wglMakeCurrent(hdc, device->plat->hrc)) { + blog(LOG_ERROR, "wglMakeCurrent failed, GetLastError " + "returned %u", GetLastError()); + blog(LOG_ERROR, "device_load_swapchain (GL) failed"); + } +} + +void device_present(device_t device) +{ + HDC hdc = device->plat->swap.wi->hdc; + if (device->cur_swap) + hdc = device->cur_swap->wi->hdc; + + if (!SwapBuffers(hdc)) { + blog(LOG_ERROR, "SwapBuffers failed, GetLastError " + "returned %u", GetLastError()); + blog(LOG_ERROR, "device_present (GL) failed"); + } +} diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index 9a0fa794921277eeb10a2e3a6cbd0485cafb2b52..d3b1dccf183e4b776879f72137706991713ded6f 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -100,8 +100,8 @@ struct gs_exports { void (*device_enable_depthtest)(device_t device, bool enable); void (*device_enable_stenciltest)(device_t device, bool enable); void (*device_enable_stencilwrite)(device_t device, bool enable); - void (*device_enable_color)(device_t device, bool red, bool blue, - bool green, bool alpha); + void (*device_enable_color)(device_t device, bool red, bool green, + bool blue, bool alpha); void (*device_blendfunction)(device_t device, enum gs_blend_type src, enum gs_blend_type dest); void (*device_depthfunction)(device_t device, enum gs_depth_test test); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index f32eb50d3ae20f6bdfa5564a7635387c6ee81ad2..f14853ad05d4625e0784cb2ac9f23728986776e9 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -1035,11 +1035,11 @@ void gs_enable_stencilwrite(bool enable) graphics->exports.device_enable_stencilwrite(graphics->device, enable); } -void gs_enable_color(bool red, bool blue, bool green, bool alpha) +void gs_enable_color(bool red, bool green, bool blue, bool alpha) { graphics_t graphics = thread_graphics; - graphics->exports.device_enable_color(graphics->device, red, blue, - green, alpha); + graphics->exports.device_enable_color(graphics->device, red, green, + blue, alpha); } void gs_blendfunction(enum gs_blend_type src, enum gs_blend_type dest) diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index a1e004149b4d03a1e506775e0c6e471af6b994a8..2b6690f28354a9351a781e1b3a3f5d289065bca3 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -586,7 +586,7 @@ EXPORT void gs_enable_blending(bool enable); EXPORT void gs_enable_depthtest(bool enable); EXPORT void gs_enable_stenciltest(bool enable); EXPORT void gs_enable_stencilwrite(bool enable); -EXPORT void gs_enable_color(bool red, bool blue, bool green, bool alpha); +EXPORT void gs_enable_color(bool red, bool green, bool blue, bool alpha); EXPORT void gs_blendfunction(enum gs_blend_type src, enum gs_blend_type dest); EXPORT void gs_depthfunction(enum gs_depth_test test);