mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
st/vega: Add SCISSOR renderer state.
The state can be used to set rectangles of the depth buffer to 0.0f. update_clip_state is changed to use the state for scissor update.
This commit is contained in:
parent
e31a04ea3b
commit
54cb382ea5
3 changed files with 122 additions and 45 deletions
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -174,6 +180,25 @@ static void renderer_set_vs(struct renderer *r, RendererVs id)
|
|||
cso_set_vertex_shader_handle(r->cso, r->cached_vs[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.
|
||||
*
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,14 @@ void renderer_drawtex(struct renderer *renderer,
|
|||
|
||||
void renderer_drawtex_end(struct renderer *renderer);
|
||||
|
||||
VGboolean renderer_scissor_begin(struct renderer *renderer,
|
||||
VGboolean restore_dsa);
|
||||
|
||||
void renderer_scissor(struct renderer *renderer,
|
||||
VGint x, VGint y, VGint width, VGint height);
|
||||
|
||||
void renderer_scissor_end(struct renderer *renderer);
|
||||
|
||||
void renderer_draw_quad(struct renderer *,
|
||||
VGfloat x1, VGfloat y1,
|
||||
VGfloat x2, VGfloat y2,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "util/u_memory.h"
|
||||
#include "util/u_blit.h"
|
||||
#include "util/u_sampler.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
struct vg_context *_vg_context = 0;
|
||||
|
||||
|
|
@ -276,65 +277,40 @@ static void update_clip_state(struct vg_context *ctx)
|
|||
memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
|
||||
|
||||
if (state->scissoring) {
|
||||
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
|
||||
struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
|
||||
int i;
|
||||
|
||||
dsa->depth.writemask = 1;/*glDepthMask(TRUE);*/
|
||||
dsa->depth.func = PIPE_FUNC_ALWAYS;
|
||||
dsa->depth.enabled = 1;
|
||||
renderer_scissor_begin(ctx->renderer, VG_FALSE);
|
||||
|
||||
cso_save_blend(ctx->cso_context);
|
||||
cso_save_fragment_shader(ctx->cso_context);
|
||||
/* set a passthrough shader */
|
||||
if (!ctx->pass_through_depth_fs)
|
||||
ctx->pass_through_depth_fs = shader_create_from_text(ctx->pipe,
|
||||
pass_through_depth_asm,
|
||||
40,
|
||||
PIPE_SHADER_FRAGMENT);
|
||||
cso_set_fragment_shader_handle(ctx->cso_context,
|
||||
ctx->pass_through_depth_fs->driver);
|
||||
cso_set_depth_stencil_alpha(ctx->cso_context, dsa);
|
||||
|
||||
ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
|
||||
|
||||
/* disable color writes */
|
||||
blend->rt[0].colormask = 0; /*disable colorwrites*/
|
||||
cso_set_blend(ctx->cso_context, blend);
|
||||
|
||||
/* enable scissoring */
|
||||
for (i = 0; i < state->scissor_rects_num; ++i) {
|
||||
const float x = state->scissor_rects[i * 4 + 0].f;
|
||||
const float y = state->scissor_rects[i * 4 + 1].f;
|
||||
const float width = state->scissor_rects[i * 4 + 2].f;
|
||||
const float height = state->scissor_rects[i * 4 + 3].f;
|
||||
VGfloat minx, miny, maxx, maxy;
|
||||
VGint x0, y0, x1, y1, iw, ih;
|
||||
|
||||
minx = 0;
|
||||
miny = 0;
|
||||
maxx = fb->width;
|
||||
maxy = fb->height;
|
||||
x0 = (VGint) x;
|
||||
y0 = (VGint) y;
|
||||
if (x0 < 0)
|
||||
x0 = 0;
|
||||
if (y0 < 0)
|
||||
y0 = 0;
|
||||
|
||||
if (x > minx)
|
||||
minx = x;
|
||||
if (y > miny)
|
||||
miny = y;
|
||||
/* note that x1 and y1 are exclusive */
|
||||
x1 = (VGint) ceilf(x + width);
|
||||
y1 = (VGint) ceilf(y + height);
|
||||
if (x1 > fb->width)
|
||||
x1 = fb->width;
|
||||
if (y1 > fb->height)
|
||||
y1 = fb->height;
|
||||
|
||||
if (x + width < maxx)
|
||||
maxx = x + width;
|
||||
if (y + height < maxy)
|
||||
maxy = y + height;
|
||||
|
||||
/* check for null space */
|
||||
if (minx >= maxx || miny >= maxy)
|
||||
minx = miny = maxx = maxy = 0;
|
||||
|
||||
/*glClear(GL_DEPTH_BUFFER_BIT);*/
|
||||
renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
|
||||
iw = x1 - x0;
|
||||
ih = y1 - y0;
|
||||
if (iw > 0 && ih> 0 )
|
||||
renderer_scissor(ctx->renderer, x0, y0, iw, ih);
|
||||
}
|
||||
|
||||
cso_restore_blend(ctx->cso_context);
|
||||
cso_restore_fragment_shader(ctx->cso_context);
|
||||
renderer_scissor_end(ctx->renderer);
|
||||
|
||||
dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
|
||||
dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue