summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/vega/renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/vega/renderer.c')
-rw-r--r--src/gallium/state_trackers/vega/renderer.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 179b6f6c834..60c4315a1fd 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -47,6 +47,7 @@ typedef enum {
RENDERER_STATE_INIT,
RENDERER_STATE_COPY,
RENDERER_STATE_DRAWTEX,
+ RENDERER_STATE_SCISSOR,
NUM_RENDERER_STATES
} RendererState;
@@ -60,6 +61,7 @@ typedef enum {
typedef enum {
RENDERER_FS_COLOR,
RENDERER_FS_TEXTURE,
+ RENDERER_FS_SCISSOR,
NUM_RENDERER_FS
} RendererFs;
@@ -89,6 +91,10 @@ struct renderer {
VGint tex_width;
VGint tex_height;
} drawtex;
+
+ struct {
+ VGboolean restore_dsa;
+ } scissor;
} u;
};
@@ -175,6 +181,25 @@ static void renderer_set_vs(struct renderer *r, RendererVs id)
}
/**
+ * Create a simple fragment shader that sets the depth to 0.0f.
+ */
+static void *create_scissor_fs(struct pipe_context *pipe)
+{
+ struct ureg_program *ureg;
+ struct ureg_dst out;
+ struct ureg_src imm;
+
+ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+ imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f);
+
+ ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm);
+ ureg_END(ureg);
+
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+/**
* Set renderer fragment shader.
*
* This function modifies fragment_shader state.
@@ -193,6 +218,9 @@ static void renderer_set_fs(struct renderer *r, RendererFs id)
fs = util_make_fragment_tex_shader(r->pipe,
TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
break;
+ case RENDERER_FS_SCISSOR:
+ fs = create_scissor_fs(r->pipe);
+ break;
default:
assert(!"Unknown renderer fs id");
break;
@@ -530,6 +558,71 @@ void renderer_drawtex_end(struct renderer *renderer)
renderer->state = RENDERER_STATE_INIT;
}
+/**
+ * Prepare the renderer for scissor update. This will reset the depth buffer
+ * to 1.0f.
+ */
+VGboolean renderer_scissor_begin(struct renderer *renderer,
+ VGboolean restore_dsa)
+{
+ struct pipe_depth_stencil_alpha_state dsa;
+
+ assert(renderer->state == RENDERER_STATE_INIT);
+
+ if (restore_dsa)
+ cso_save_depth_stencil_alpha(renderer->cso);
+ cso_save_blend(renderer->cso);
+ cso_save_fragment_shader(renderer->cso);
+
+ /* enable depth writes */
+ memset(&dsa, 0, sizeof(dsa));
+ dsa.depth.enabled = 1;
+ dsa.depth.writemask = 1;
+ dsa.depth.func = PIPE_FUNC_ALWAYS;
+ cso_set_depth_stencil_alpha(renderer->cso, &dsa);
+
+ /* disable color writes */
+ renderer_set_blend(renderer, 0);
+ renderer_set_fs(renderer, RENDERER_FS_SCISSOR);
+
+ renderer->u.scissor.restore_dsa = restore_dsa;
+ renderer->state = RENDERER_STATE_SCISSOR;
+
+ /* clear the depth buffer to 1.0f */
+ renderer->pipe->clear(renderer->pipe,
+ PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0f, 0);
+
+ return VG_TRUE;
+}
+
+/**
+ * Add a scissor rectangle. Depth values inside the rectangle will be set to
+ * 0.0f.
+ */
+void renderer_scissor(struct renderer *renderer,
+ VGint x, VGint y, VGint width, VGint height)
+{
+ assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+ renderer_quad_pos(renderer, x, y, x + width, y + height, VG_FALSE);
+ renderer_quad_draw(renderer);
+}
+
+/**
+ * End scissor update and restore the states.
+ */
+void renderer_scissor_end(struct renderer *renderer)
+{
+ assert(renderer->state == RENDERER_STATE_SCISSOR);
+
+ if (renderer->u.scissor.restore_dsa)
+ cso_restore_depth_stencil_alpha(renderer->cso);
+ cso_restore_blend(renderer->cso);
+ cso_restore_fragment_shader(renderer->cso);
+
+ renderer->state = RENDERER_STATE_INIT;
+}
+
static void setup_shaders(struct renderer *ctx)
{
struct pipe_context *pipe = ctx->pipe;