From fae7786c8d62732421944d5d4bee865d982e4b36 Mon Sep 17 00:00:00 2001 From: bjorn Date: Tue, 25 Dec 2018 00:20:59 -0800 Subject: [PATCH] Simplify Pipeline; --- src/graphics/graphics.c | 97 ++++++++++++++++++----------------------- src/graphics/graphics.h | 8 +--- src/headset/oculus.c | 6 ++- src/headset/openvr.c | 6 ++- 4 files changed, 52 insertions(+), 65 deletions(-) diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 0f8de129..be8df1b6 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -55,9 +55,6 @@ bool lovrGraphicsInit(bool gammaCorrect) { void lovrGraphicsDestroy() { if (!state.initialized) return; - while (state.pipelineIndex > 0) { - lovrGraphicsPopPipeline(); - } lovrGraphicsSetShader(NULL); lovrGraphicsSetFont(NULL); lovrGraphicsSetCanvas(NULL); @@ -167,10 +164,6 @@ Buffer* lovrGraphicsGetIdentityBuffer() { // State void lovrGraphicsReset() { - while (state.pipelineIndex > 0) { - lovrGraphicsPopPipeline(); - } - state.pipeline = &state.pipelines[state.pipelineIndex]; state.transform = 0; lovrGraphicsSetCamera(NULL, false); lovrGraphicsSetBackgroundColor((Color) { 0, 0, 0, 1 }); @@ -190,23 +183,12 @@ void lovrGraphicsReset() { lovrGraphicsOrigin(); } -void lovrGraphicsPushPipeline() { - lovrAssert(++state.pipelineIndex < MAX_PIPELINES, "Unbalanced pipeline stack (more pushes than pops?)"); - memcpy(&state.pipelines[state.pipelineIndex], &state.pipelines[state.pipelineIndex - 1], sizeof(Pipeline)); - state.pipeline = &state.pipelines[state.pipelineIndex]; -} - -void lovrGraphicsPopPipeline() { - lovrAssert(--state.pipelineIndex >= 0, "Unbalanced pipeline stack (more pops than pushes?)"); - state.pipeline = &state.pipelines[state.pipelineIndex]; -} - bool lovrGraphicsGetAlphaSampling() { - return state.pipeline->alphaSampling; + return state.pipeline.alphaSampling; } void lovrGraphicsSetAlphaSampling(bool sample) { - state.pipeline->alphaSampling = sample; + state.pipeline.alphaSampling = sample; } Color lovrGraphicsGetBackgroundColor() { @@ -218,13 +200,13 @@ void lovrGraphicsSetBackgroundColor(Color color) { } void lovrGraphicsGetBlendMode(BlendMode* mode, BlendAlphaMode* alphaMode) { - *mode = state.pipeline->blendMode; - *alphaMode = state.pipeline->blendAlphaMode; + *mode = state.pipeline.blendMode; + *alphaMode = state.pipeline.blendAlphaMode; } void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) { - state.pipeline->blendMode = mode; - state.pipeline->blendAlphaMode = alphaMode; + state.pipeline.blendMode = mode; + state.pipeline.blendAlphaMode = alphaMode; } Canvas* lovrGraphicsGetCanvas() { @@ -250,11 +232,11 @@ void lovrGraphicsSetColor(Color color) { } bool lovrGraphicsIsCullingEnabled() { - return state.pipeline->culling; + return state.pipeline.culling; } void lovrGraphicsSetCullingEnabled(bool culling) { - state.pipeline->culling = culling; + state.pipeline.culling = culling; } TextureFilter lovrGraphicsGetDefaultFilter() { @@ -266,13 +248,13 @@ void lovrGraphicsSetDefaultFilter(TextureFilter filter) { } void lovrGraphicsGetDepthTest(CompareMode* mode, bool* write) { - *mode = state.pipeline->depthTest; - *write = state.pipeline->depthWrite; + *mode = state.pipeline.depthTest; + *write = state.pipeline.depthWrite; } void lovrGraphicsSetDepthTest(CompareMode mode, bool write) { - state.pipeline->depthTest = mode; - state.pipeline->depthWrite = write; + state.pipeline.depthTest = mode; + state.pipeline.depthWrite = write; } Font* lovrGraphicsGetFont() { @@ -300,12 +282,12 @@ bool lovrGraphicsIsGammaCorrect() { } float lovrGraphicsGetLineWidth() { - return state.pipeline->lineWidth; + return state.pipeline.lineWidth; } void lovrGraphicsSetLineWidth(uint8_t width) { lovrAssert(width > 0 && width <= 255, "Line width must be between 0 and 255"); - state.pipeline->lineWidth = width; + state.pipeline.lineWidth = width; } float lovrGraphicsGetPointSize() { @@ -328,30 +310,30 @@ void lovrGraphicsSetShader(Shader* shader) { } void lovrGraphicsGetStencilTest(CompareMode* mode, int* value) { - *mode = state.pipeline->stencilMode; - *value = state.pipeline->stencilValue; + *mode = state.pipeline.stencilMode; + *value = state.pipeline.stencilValue; } void lovrGraphicsSetStencilTest(CompareMode mode, int value) { - state.pipeline->stencilMode = mode; - state.pipeline->stencilValue = value; + state.pipeline.stencilMode = mode; + state.pipeline.stencilValue = value; } Winding lovrGraphicsGetWinding() { - return state.pipeline->winding; + return state.pipeline.winding; } void lovrGraphicsSetWinding(Winding winding) { - state.pipeline->winding = winding; + state.pipeline.winding = winding; } bool lovrGraphicsIsWireframe() { - return state.pipeline->wireframe; + return state.pipeline.wireframe; } void lovrGraphicsSetWireframe(bool wireframe) { #ifndef EMSCRIPTEN - state.pipeline->wireframe = wireframe; + state.pipeline.wireframe = wireframe; #endif } @@ -435,6 +417,7 @@ void lovrGraphicsFlush() { Canvas* canvas = state.canvas ? state.canvas : state.camera.canvas; Material* material = draw->material ? draw->material : (state.defaultMaterial ? state.defaultMaterial : (state.defaultMaterial = lovrMaterialCreate())); Shader* shader = state.shader ? state.shader : (state.defaultShaders[draw->shader] ? state.defaultShaders[draw->shader] : (state.defaultShaders[draw->shader] = lovrShaderCreateDefault(draw->shader))); + Pipeline* pipeline = draw->pipeline ? draw->pipeline : &state.pipeline; if (!draw->material) { lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, draw->diffuseTexture); @@ -480,7 +463,7 @@ void lovrGraphicsFlush() { .mesh = mesh, .shader = shader, .canvas = canvas, - .pipeline = *state.pipeline, + .pipeline = *pipeline, .instances = draw->instances, .width = canvas ? lovrCanvasGetWidth(canvas) : state.width, .height = canvas ? lovrCanvasGetHeight(canvas) : state.height, @@ -876,12 +859,15 @@ void lovrGraphicsSphere(Material* material, mat4 transform, int segments) { void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float az) { TextureType type = lovrTextureGetType(texture); lovrAssert(type == TEXTURE_CUBE || type == TEXTURE_2D, "Only 2D and cube textures can be used as skyboxes"); - lovrGraphicsPushPipeline(); - lovrGraphicsSetWinding(WINDING_COUNTERCLOCKWISE); + + Pipeline pipeline = state.pipeline; + pipeline.winding = WINDING_COUNTERCLOCKWISE; + lovrGraphicsDraw(&(DrawRequest) { .shader = type == TEXTURE_CUBE ? SHADER_CUBE : SHADER_PANO, .diffuseTexture = type == TEXTURE_2D ? texture : NULL, .environmentMap = type == TEXTURE_CUBE ? texture : NULL, + .pipeline = &pipeline, .mode = DRAW_TRIANGLE_STRIP, .vertex.count = 4, .vertex.data = (float[]) { @@ -891,7 +877,6 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float 1, -1, 1, 0, 0, 0, 0, 0 } }); - lovrGraphicsPopPipeline(); } void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign) { @@ -903,29 +888,32 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl float* vertices = lovrGraphicsGetVertexPointer(maxVertices); lovrFontRender(font, str, wrap, halign, valign, vertices, &offsety, &vertexCount); - lovrGraphicsPush(); - lovrGraphicsMatrixTransform(transform); - lovrGraphicsScale((float[3]) { scale, scale, scale }); - lovrGraphicsTranslate((float[3]) { 0, offsety, 0 }); - lovrGraphicsPushPipeline(); - lovrGraphicsSetAlphaSampling(true); + Pipeline pipeline = state.pipeline; + pipeline.alphaSampling = true; + + mat4_scale(transform, scale, scale, scale); + mat4_translate(transform, 0.f, offsety, 0.f); + lovrGraphicsDraw(&(DrawRequest) { .shader = SHADER_FONT, .diffuseTexture = font->texture, + .pipeline = &pipeline, + .transform = transform, .mode = DRAW_TRIANGLES, .vertex.count = vertexCount }); - lovrGraphicsPopPipeline(); - lovrGraphicsPop(); } void lovrGraphicsFill(Texture* texture, float u, float v, float w, float h) { - lovrGraphicsPushPipeline(); - lovrGraphicsSetDepthTest(COMPARE_NONE, false); + Pipeline pipeline = state.pipeline; + pipeline.depthTest = COMPARE_NONE; + pipeline.depthWrite = false; + lovrGraphicsDraw(&(DrawRequest) { .mono = true, .shader = SHADER_FILL, .diffuseTexture = texture, + .pipeline = &pipeline, .mode = DRAW_TRIANGLE_STRIP, .vertex.count = 4, .vertex.data = (float[]) { @@ -935,5 +923,4 @@ void lovrGraphicsFill(Texture* texture, float u, float v, float w, float h) { 1, -1, 0, 0, 0, 0, u + w, v } }); - lovrGraphicsPopPipeline(); } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 13d018cc..83edd5d3 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -13,7 +13,6 @@ #pragma once #define MAX_TRANSFORMS 64 -#define MAX_PIPELINES 16 #define MAX_VERTICES (1 << 16) #define MAX_INDICES (1 << 16) #define MAX_BATCH_SIZE 192 // Enough to fit in any UBO @@ -122,6 +121,7 @@ typedef struct { Texture* diffuseTexture; Texture* environmentMap; Material* material; + Pipeline* pipeline; mat4 transform; float* pose; int instances; @@ -141,13 +141,11 @@ typedef struct { TextureFilter defaultFilter; float transforms[MAX_TRANSFORMS][16]; int transform; - Pipeline pipelines[MAX_PIPELINES]; - Pipeline* pipeline; - int pipelineIndex; Color backgroundColor; Canvas* canvas; Color color; Font* font; + Pipeline pipeline; float pointSize; Shader* shader; DrawRequest batch; @@ -176,8 +174,6 @@ Buffer* lovrGraphicsGetIdentityBuffer(); // State void lovrGraphicsReset(); -void lovrGraphicsPushPipeline(); -void lovrGraphicsPopPipeline(); bool lovrGraphicsGetAlphaSampling(); void lovrGraphicsSetAlphaSampling(bool sample); Color lovrGraphicsGetBackgroundColor(); diff --git a/src/headset/oculus.c b/src/headset/oculus.c index 3d311cca..3e5c46a2 100644 --- a/src/headset/oculus.c +++ b/src/headset/oculus.c @@ -436,7 +436,8 @@ static void oculusRenderTo(void (*callback)(void*), void* userdata) { uint32_t handle; ovr_GetMirrorTextureBufferGL(state.session, state.mirror, &handle); Texture* texture = lookupTexture(handle); - lovrGraphicsPushPipeline(); + Color oldColor = lovrGraphicsGetColor(); + Shader* oldShader = lovrGraphicsGetShader(); lovrGraphicsSetColor((Color) { 1, 1, 1, 1 }); lovrGraphicsSetShader(NULL); if (state.mirrorEye == EYE_BOTH) { @@ -444,7 +445,8 @@ static void oculusRenderTo(void (*callback)(void*), void* userdata) { } else { lovrGraphicsFill(texture, .5 * state.mirrorEye, 0, .5, 1); } - lovrGraphicsPopPipeline(); + lovrGraphicsSetColor(oldColor); + lovrGraphicsSetShader(oldShader); } } diff --git a/src/headset/openvr.c b/src/headset/openvr.c index 3055a0a1..d28a1074 100644 --- a/src/headset/openvr.c +++ b/src/headset/openvr.c @@ -530,7 +530,8 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) { lovrGpuDirtyTexture(); if (state.isMirrored) { - lovrGraphicsPushPipeline(); + Color oldColor = lovrGraphicsGetColor(); + Shader* oldShader = lovrGraphicsGetShader(); lovrGraphicsSetColor((Color) { 1, 1, 1, 1 }); lovrGraphicsSetShader(NULL); if (state.mirrorEye == EYE_BOTH) { @@ -538,7 +539,8 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) { } else { lovrGraphicsFill(attachments[0].texture, .5 * state.mirrorEye, 0, .5, 1); } - lovrGraphicsPopPipeline(); + lovrGraphicsSetColor(oldColor); + lovrGraphicsSetShader(oldShader); } }