Needs testing.
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->rasterizer = raster;
- draw->bypass_clipping =
- ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) ||
- draw->driver.bypass_clipping);
+ draw->bypass_clipping = draw->driver.bypass_clipping;
}
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->driver.bypass_clipping = bypass_clipping;
- draw->bypass_clipping =
- ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) ||
- draw->driver.bypass_clipping);
+ draw->bypass_clipping = draw->driver.bypass_clipping;
}
opt |= PT_CLIPTEST;
}
- if (!draw->rasterizer->bypass_vs_clip_and_viewport) {
- opt |= PT_SHADE;
- }
+ opt |= PT_SHADE;
}
if (opt == 0)
fse->key.nr_elements = MAX2(fse->key.nr_outputs, /* outputs - translate to hw format */
fse->key.nr_inputs); /* inputs - fetch from api format */
- fse->key.viewport = (!draw->rasterizer->bypass_vs_clip_and_viewport &&
- !draw->identity_viewport);
+ fse->key.viewport = !draw->identity_viewport;
fse->key.clip = !draw->bypass_clipping;
fse->key.const_vbuffers = 0;
*/
draw_pt_post_vs_prepare( fpme->post_vs,
(boolean)draw->bypass_clipping,
- (boolean)(draw->identity_viewport ||
- draw->rasterizer->bypass_vs_clip_and_viewport),
+ (boolean)draw->identity_viewport,
(boolean)draw->rasterizer->gl_rasterization_rules,
(draw->vs.edgeflag_output ? true : false) );
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
- * the pipeline verts. If there is no shader, eg if
- * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
- * already in the correct place.
+ * the pipeline verts.
*/
if (opt & PT_SHADE)
{
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
- * the pipeline verts. If there is no shader, ie if
- * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
- * already in the correct place.
+ * the pipeline verts.
*/
if (opt & PT_SHADE)
{
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
- * the pipeline verts. If there is no shader, ie if
- * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
- * already in the correct place.
+ * the pipeline verts.
*/
if (opt & PT_SHADE)
{
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
ctx->rasterizer.front_winding = PIPE_WINDING_CW;
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
- ctx->rasterizer.bypass_vs_clip_and_viewport = 1;
ctx->rasterizer.gl_rasterization_rules = 1;
/* samplers */
ctx->sampler.mag_img_filter = 0; /* set later */
ctx->sampler.normalized_coords = 1;
-
/* vertex shader - still required to provide the linkage between
* fragment shader input semantics and vertex_element/buffers.
*/
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
cso_save_sampler_textures(ctx->cso);
+ cso_save_viewport(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_single_sampler(ctx->cso, 0, &ctx->sampler);
cso_single_sampler_done(ctx->cso);
+ /* viewport */
+ ctx->viewport.scale[0] = 0.5f * dst->width;
+ ctx->viewport.scale[1] = 0.5f * dst->height;
+ ctx->viewport.scale[2] = 1.0f;
+ ctx->viewport.scale[3] = 1.0f;
+ ctx->viewport.translate[0] = 0.5f * dst->width;
+ ctx->viewport.translate[1] = 0.5f * dst->height;
+ ctx->viewport.translate[2] = 0.0f;
+ ctx->viewport.translate[3] = 0.0f;
+ cso_set_viewport(ctx->cso, &ctx->viewport);
+
/* texture */
cso_set_sampler_textures(ctx->cso, 1, &tex);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
cso_restore_sampler_textures(ctx->cso);
+ cso_restore_viewport(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
memset(&rs_state, 0, sizeof(rs_state));
rs_state.front_winding = PIPE_WINDING_CW;
rs_state.cull_mode = PIPE_WINDING_NONE;
- rs_state.bypass_vs_clip_and_viewport = 1;
rs_state.gl_rasterization_rules = 1;
rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
util_dump_member(stream, uint, state, line_stipple_factor);
util_dump_member(stream, uint, state, line_stipple_pattern);
util_dump_member(stream, bool, state, line_last_pixel);
- util_dump_member(stream, bool, state, bypass_vs_clip_and_viewport);
util_dump_member(stream, bool, state, flatshade_first);
util_dump_member(stream, bool, state, gl_rasterization_rules);
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
ctx->rasterizer.front_winding = PIPE_WINDING_CW;
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
- ctx->rasterizer.bypass_vs_clip_and_viewport = 1;
ctx->rasterizer.gl_rasterization_rules = 1;
/* sampler state */
static unsigned
set_vertex_data(struct gen_mipmap_state *ctx,
enum pipe_texture_target tex_target,
- uint face, float width, float height)
+ uint face)
{
unsigned offset;
/* vert[0].position */
- ctx->vertices[0][0][0] = 0.0f; /*x*/
- ctx->vertices[0][0][1] = 0.0f; /*y*/
+ ctx->vertices[0][0][0] = -1.0f; /*x*/
+ ctx->vertices[0][0][1] = -1.0f; /*y*/
/* vert[1].position */
- ctx->vertices[1][0][0] = width;
- ctx->vertices[1][0][1] = 0.0f;
+ ctx->vertices[1][0][0] = 1.0f;
+ ctx->vertices[1][0][1] = -1.0f;
/* vert[2].position */
- ctx->vertices[2][0][0] = width;
- ctx->vertices[2][0][1] = height;
+ ctx->vertices[2][0][0] = 1.0f;
+ ctx->vertices[2][0][1] = 1.0f;
/* vert[3].position */
- ctx->vertices[3][0][0] = 0.0f;
- ctx->vertices[3][0][1] = height;
+ ctx->vertices[3][0][0] = -1.0f;
+ ctx->vertices[3][0][1] = 1.0f;
/* Setup vertex texcoords. This is a little tricky for cube maps. */
if (tex_target == PIPE_TEXTURE_CUBE) {
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
+ cso_save_viewport(ctx->cso);
/* bind our state */
cso_set_blend(ctx->cso, &ctx->blend);
*/
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
+ struct pipe_viewport_state vp;
struct pipe_surface *surf =
screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
fb.height = u_minify(pt->height0, dstLevel);
cso_set_framebuffer(ctx->cso, &fb);
+ /* viewport */
+ vp.scale[0] = 0.5f * fb.width;
+ vp.scale[1] = 0.5f * fb.height;
+ vp.scale[2] = 1.0f;
+ vp.scale[3] = 1.0f;
+ vp.translate[0] = 0.5f * fb.width;
+ vp.translate[1] = 0.5f * fb.height;
+ vp.translate[2] = 0.0f;
+ vp.translate[3] = 0.0f;
+ cso_set_viewport(ctx->cso, &vp);
+
/*
* Setup sampler state
* Note: we should only have to set the min/max LOD clamps to ensure
cso_set_sampler_textures(ctx->cso, 1, &pt);
- /* quad coords in window coords (bypassing vs, clip and viewport) */
+ /* quad coords in clip coords */
offset = set_vertex_data(ctx,
pt->target,
- face,
- (float) u_minify(pt->width0, dstLevel),
- (float) u_minify(pt->height0, dstLevel));
+ face);
util_draw_vertex_buffer(ctx->pipe,
ctx->vbuf,
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
+ cso_restore_viewport(ctx->cso);
}
Members
-------
-bypass_vs_clip_and_viewport
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Whether the entire TCL pipeline should be bypassed. This implies that
-vertices are pre-transformed for the viewport, and will not be run
-through the vertex shader.
-
-.. note::
-
- Implementations may still clip away vertices that are not in the viewport
- when this is set.
-
flatshade
^^^^^^^^^
struct nv30_state {
unsigned scissor_enabled;
unsigned stipple_enabled;
- unsigned viewport_bypass;
unsigned fp_samplers;
uint64_t dirty;
{
struct pipe_viewport_state *vpt = &nv30->viewport;
struct nouveau_stateobj *so;
- unsigned bypass;
-
- if (/*nv30->render_mode == HW &&*/
- !nv30->rasterizer->pipe.bypass_vs_clip_and_viewport)
- bypass = 0;
- else
- bypass = 1;
if (nv30->state.hw[NV30_STATE_VIEWPORT] &&
- (bypass || !(nv30->dirty & NV30_NEW_VIEWPORT)) &&
- nv30->state.viewport_bypass == bypass)
+ !(nv30->dirty & NV30_NEW_VIEWPORT))
return FALSE;
- nv30->state.viewport_bypass = bypass;
so = so_new(3, 10, 0);
- if (!bypass) {
- so_method(so, nv30->screen->rankine,
- NV34TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(vpt->translate[0]));
- so_data (so, fui(vpt->translate[1]));
- so_data (so, fui(vpt->translate[2]));
- so_data (so, fui(vpt->translate[3]));
- so_data (so, fui(vpt->scale[0]));
- so_data (so, fui(vpt->scale[1]));
- so_data (so, fui(vpt->scale[2]));
- so_data (so, fui(vpt->scale[3]));
-/* so_method(so, nv30->screen->rankine, 0x1d78, 1);
- so_data (so, 1);
-*/ } else {
- so_method(so, nv30->screen->rankine,
- NV34TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
- so_data (so, fui(1.0));
- so_data (so, fui(1.0));
- so_data (so, fui(0.0));
- /* Not entirely certain what this is yet. The DDX uses this
- * value also as it fixes rendering when you pass
- * pre-transformed vertices to the GPU. My best gusss is that
- * this bypasses some culling/clipping stage. Might be worth
- * noting that points/lines are uneffected by whatever this
- * value fixes, only filled polygons are effected.
- */
-/* so_method(so, nv30->screen->rankine, 0x1d78, 1);
- so_data (so, 0x110);
-*/ }
+ so_method(so, nv30->screen->rankine,
+ NV34TCL_VIEWPORT_TRANSLATE_X, 8);
+ so_data (so, fui(vpt->translate[0]));
+ so_data (so, fui(vpt->translate[1]));
+ so_data (so, fui(vpt->translate[2]));
+ so_data (so, fui(vpt->translate[3]));
+ so_data (so, fui(vpt->scale[0]));
+ so_data (so, fui(vpt->scale[1]));
+ so_data (so, fui(vpt->scale[2]));
+ so_data (so, fui(vpt->scale[3]));
+/* so_method(so, nv30->screen->rankine, 0x1d78, 1);
+ so_data (so, 1);
+*/
/* TODO/FIXME: never saw value 0x0110 in renouveau dumps, only 0x0001 */
so_method(so, nv30->screen->rankine, 0x1d78, 1);
so_data (so, 1);
struct nv40_state {
unsigned scissor_enabled;
unsigned stipple_enabled;
- unsigned viewport_bypass;
unsigned fp_samplers;
uint64_t dirty;
{
struct pipe_viewport_state *vpt = &nv40->viewport;
struct nouveau_stateobj *so;
- unsigned bypass;
-
- if (nv40->render_mode == HW &&
- !nv40->rasterizer->pipe.bypass_vs_clip_and_viewport)
- bypass = 0;
- else
- bypass = 1;
if (nv40->state.hw[NV40_STATE_VIEWPORT] &&
- (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) &&
- nv40->state.viewport_bypass == bypass)
+ !(nv40->dirty & NV40_NEW_VIEWPORT))
return FALSE;
- nv40->state.viewport_bypass = bypass;
so = so_new(2, 9, 0);
- if (!bypass) {
- so_method(so, nv40->screen->curie,
- NV40TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(vpt->translate[0]));
- so_data (so, fui(vpt->translate[1]));
- so_data (so, fui(vpt->translate[2]));
- so_data (so, fui(vpt->translate[3]));
- so_data (so, fui(vpt->scale[0]));
- so_data (so, fui(vpt->scale[1]));
- so_data (so, fui(vpt->scale[2]));
- so_data (so, fui(vpt->scale[3]));
- so_method(so, nv40->screen->curie, 0x1d78, 1);
- so_data (so, 1);
- } else {
- so_method(so, nv40->screen->curie,
- NV40TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
- so_data (so, fui(1.0));
- so_data (so, fui(1.0));
- so_data (so, fui(0.0));
- /* Not entirely certain what this is yet. The DDX uses this
- * value also as it fixes rendering when you pass
- * pre-transformed vertices to the GPU. My best gusss is that
- * this bypasses some culling/clipping stage. Might be worth
- * noting that points/lines are uneffected by whatever this
- * value fixes, only filled polygons are effected.
- */
- so_method(so, nv40->screen->curie, 0x1d78, 1);
- so_data (so, 0x110);
- }
+ so_method(so, nv40->screen->curie,
+ NV40TCL_VIEWPORT_TRANSLATE_X, 8);
+ so_data (so, fui(vpt->translate[0]));
+ so_data (so, fui(vpt->translate[1]));
+ so_data (so, fui(vpt->translate[2]));
+ so_data (so, fui(vpt->translate[3]));
+ so_data (so, fui(vpt->scale[0]));
+ so_data (so, fui(vpt->scale[1]));
+ so_data (so, fui(vpt->scale[2]));
+ so_data (so, fui(vpt->scale[3]));
+ so_method(so, nv40->screen->curie, 0x1d78, 1);
+ so_data (so, 1);
so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]);
so_ref(NULL, &so);
struct nouveau_stateobj *scissor;
unsigned scissor_enabled;
struct nouveau_stateobj *viewport;
- unsigned viewport_bypass;
struct nouveau_stateobj *tsc_upload;
struct nouveau_stateobj *tic_upload;
unsigned miptree_nr[PIPE_SHADER_TYPES];
scissor_uptodate:
if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
- unsigned bypass;
-
- if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport)
- bypass = 0;
- else
- bypass = 1;
-
if (nv50->state.viewport &&
- (bypass || !(nv50->dirty & NV50_NEW_VIEWPORT)) &&
- nv50->state.viewport_bypass == bypass)
+ !(nv50->dirty & NV50_NEW_VIEWPORT))
goto viewport_uptodate;
- nv50->state.viewport_bypass = bypass;
so = so_new(5, 9, 0);
- if (!bypass) {
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
- so_data (so, fui(nv50->viewport.translate[0]));
- so_data (so, fui(nv50->viewport.translate[1]));
- so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
- so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(nv50->viewport.scale[1]));
- so_data (so, fui(nv50->viewport.scale[2]));
-
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
- so_data (so, 1);
- /* 0x0000 = remove whole primitive only (xyz)
- * 0x1018 = remove whole primitive only (xy), clamp z
- * 0x1080 = clip primitive (xyz)
- * 0x1098 = clip primitive (xy), clamp z
- */
- so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
- so_data (so, 0x1080);
- /* no idea what 0f90 does */
- so_method(so, tesla, 0x0f90, 1);
- so_data (so, 0);
- } else {
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
- so_data (so, 0);
- so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
- so_data (so, 0x0000);
- so_method(so, tesla, 0x0f90, 1);
- so_data (so, 1);
- }
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
+ so_data (so, fui(nv50->viewport.translate[0]));
+ so_data (so, fui(nv50->viewport.translate[1]));
+ so_data (so, fui(nv50->viewport.translate[2]));
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
+ so_data (so, fui(nv50->viewport.scale[0]));
+ so_data (so, fui(nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[2]));
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+ so_data (so, 1);
+ /* 0x0000 = remove whole primitive only (xyz)
+ * 0x1018 = remove whole primitive only (xy), clamp z
+ * 0x1080 = clip primitive (xyz)
+ * 0x1098 = clip primitive (xy), clamp z
+ */
+ so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+ so_data (so, 0x1080);
+ /* no idea what 0f90 does */
+ so_method(so, tesla, 0x0f90, 1);
+ so_data (so, 0);
so_ref(so, &nv50->state.viewport);
so_ref(NULL, &so);
uint32_t dirty_state;
/* Flag indicating whether or not the HW is dirty. */
uint32_t dirty_hw;
- /* Whether the TCL engine should be in bypass mode. */
- boolean tcl_bypass;
/* Whether polygon offset is enabled. */
boolean polygon_offset_enabled;
/* Z buffer bit depth. */
break;
case RC_STATE_R300_VIEWPORT_SCALE:
- if (r300->tcl_bypass) {
- vec[0] = 1;
- vec[1] = 1;
- vec[2] = 1;
- } else {
- vec[0] = viewport->xscale;
- vec[1] = viewport->yscale;
- vec[2] = viewport->zscale;
- }
+ vec[0] = viewport->xscale;
+ vec[1] = viewport->yscale;
+ vec[2] = viewport->zscale;
break;
case RC_STATE_R300_VIEWPORT_OFFSET:
- if (!r300->tcl_bypass) {
- vec[0] = viewport->xoffset;
- vec[1] = viewport->yoffset;
- vec[2] = viewport->zoffset;
- }
+ vec[0] = viewport->xoffset;
+ vec[1] = viewport->yoffset;
+ vec[2] = viewport->zoffset;
break;
default:
struct r300_viewport_state* viewport = (struct r300_viewport_state*)state;
CS_LOCALS(r300);
- if (r300->tcl_bypass) {
- BEGIN_CS(2);
- OUT_CS_REG(R300_VAP_VTE_CNTL, 0);
- END_CS;
- } else {
- BEGIN_CS(9);
- OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
- OUT_CS_32F(viewport->xscale);
- OUT_CS_32F(viewport->xoffset);
- OUT_CS_32F(viewport->yscale);
- OUT_CS_32F(viewport->yoffset);
- OUT_CS_32F(viewport->zscale);
- OUT_CS_32F(viewport->zoffset);
- OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
- END_CS;
- }
+ BEGIN_CS(9);
+ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
+ OUT_CS_32F(viewport->xscale);
+ OUT_CS_32F(viewport->xoffset);
+ OUT_CS_32F(viewport->yscale);
+ OUT_CS_32F(viewport->yoffset);
+ OUT_CS_32F(viewport->zscale);
+ OUT_CS_32F(viewport->zoffset);
+ OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+ END_CS;
}
void r300_emit_texture_count(struct r300_context* r300)
/* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
* Else, enable HW TCL and force Draw's TCL off. */
- if (state->bypass_vs_clip_and_viewport ||
- !r300screen->caps->has_tcl) {
+ if (!r300screen->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
}
if (rs) {
- r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport;
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
} else {
- r300->tcl_bypass = FALSE;
r300->polygon_offset_enabled = FALSE;
}
int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int* stream_tab;
- /* If TCL is bypassed, map vertex streams to equivalent VS output
- * locations. */
- if (r300->tcl_bypass) {
- stream_tab = r300->vs->stream_loc_notcl;
- } else {
- stream_tab = identity;
- }
+ stream_tab = identity;
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
rast.line_stipple_factor = 0;
rast.line_stipple_pattern = 0;
rast.line_last_pixel = 0;
- rast.bypass_vs_clip_and_viewport = 0;
rast.line_width = 1;
rast.point_smooth = 0;
rast.point_quad_rasterization = 0;
float fb_width = svga->curr.framebuffer.width;
float fb_height = svga->curr.framebuffer.height;
- memset( &prescale, 0, sizeof(prescale) );
-
- if (svga->curr.rast->templ.bypass_vs_clip_and_viewport) {
-
- /* Avoid POSITIONT as it has a non trivial implementation outside the D3D
- * API. Always generate a vertex shader.
- */
- rect.x = 0;
- rect.y = 0;
- rect.w = svga->curr.framebuffer.width;
- rect.h = svga->curr.framebuffer.height;
-
- prescale.scale[0] = 2.0 / (float)rect.w;
- prescale.scale[1] = - 2.0 / (float)rect.h;
- prescale.scale[2] = 1.0;
- prescale.scale[3] = 1.0;
- prescale.translate[0] = -1.0f;
- prescale.translate[1] = 1.0f;
- prescale.translate[2] = 0;
- prescale.translate[3] = 0;
- prescale.enabled = TRUE;
- } else {
-
- /* Examine gallium viewport transformation and produce a screen
- * rectangle and possibly vertex shader pre-transformation to
- * get the same results.
- */
- float fx = viewport->scale[0] * -1.0 + viewport->translate[0];
- float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
- float fw = viewport->scale[0] * 2;
- float fh = flip * viewport->scale[1] * 2;
-
- SVGA_DBG(DEBUG_VIEWPORT,
- "\ninitial %f,%f %fx%f\n",
- fx,
- fy,
- fw,
- fh);
-
- prescale.scale[0] = 1.0;
- prescale.scale[1] = 1.0;
- prescale.scale[2] = 1.0;
- prescale.scale[3] = 1.0;
- prescale.translate[0] = 0;
- prescale.translate[1] = 0;
- prescale.translate[2] = 0;
- prescale.translate[3] = 0;
- prescale.enabled = TRUE;
-
-
-
- if (fw < 0) {
- prescale.scale[0] *= -1.0;
- prescale.translate[0] += -fw;
- fw = -fw;
- fx = viewport->scale[0] * 1.0 + viewport->translate[0];
- }
+ float fx = viewport->scale[0] * -1.0 + viewport->translate[0];
+ float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
+ float fw = viewport->scale[0] * 2;
+ float fh = flip * viewport->scale[1] * 2;
- if (fh < 0) {
- prescale.scale[1] *= -1.0;
- prescale.translate[1] += -fh;
- fh = -fh;
- fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
- }
+ memset( &prescale, 0, sizeof(prescale) );
- if (fx < 0) {
- prescale.translate[0] += fx;
- prescale.scale[0] *= fw / (fw + fx);
- fw += fx;
- fx = 0;
- }
+ /* Examine gallium viewport transformation and produce a screen
+ * rectangle and possibly vertex shader pre-transformation to
+ * get the same results.
+ */
- if (fy < 0) {
- prescale.translate[1] += fy;
- prescale.scale[1] *= fh / (fh + fy);
- fh += fy;
- fy = 0;
- }
+ SVGA_DBG(DEBUG_VIEWPORT,
+ "\ninitial %f,%f %fx%f\n",
+ fx,
+ fy,
+ fw,
+ fh);
+
+ prescale.scale[0] = 1.0;
+ prescale.scale[1] = 1.0;
+ prescale.scale[2] = 1.0;
+ prescale.scale[3] = 1.0;
+ prescale.translate[0] = 0;
+ prescale.translate[1] = 0;
+ prescale.translate[2] = 0;
+ prescale.translate[3] = 0;
+ prescale.enabled = TRUE;
+
+
+
+ if (fw < 0) {
+ prescale.scale[0] *= -1.0;
+ prescale.translate[0] += -fw;
+ fw = -fw;
+ fx = viewport->scale[0] * 1.0 + viewport->translate[0];
+ }
- if (fx + fw > fb_width) {
- prescale.scale[0] *= fw / (fb_width - fx);
- prescale.translate[0] -= fx * (fw / (fb_width - fx));
- prescale.translate[0] += fx;
- fw = fb_width - fx;
-
- }
+ if (fh < 0) {
+ prescale.scale[1] *= -1.0;
+ prescale.translate[1] += -fh;
+ fh = -fh;
+ fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
+ }
- if (fy + fh > fb_height) {
- prescale.scale[1] *= fh / (fb_height - fy);
- prescale.translate[1] -= fy * (fh / (fb_height - fy));
- prescale.translate[1] += fy;
- fh = fb_height - fy;
- }
+ if (fx < 0) {
+ prescale.translate[0] += fx;
+ prescale.scale[0] *= fw / (fw + fx);
+ fw += fx;
+ fx = 0;
+ }
- if (fw < 0 || fh < 0) {
- fw = fh = fx = fy = 0;
- degenerate = TRUE;
- goto out;
- }
+ if (fy < 0) {
+ prescale.translate[1] += fy;
+ prescale.scale[1] *= fh / (fh + fy);
+ fh += fy;
+ fy = 0;
+ }
+ if (fx + fw > fb_width) {
+ prescale.scale[0] *= fw / (fb_width - fx);
+ prescale.translate[0] -= fx * (fw / (fb_width - fx));
+ prescale.translate[0] += fx;
+ fw = fb_width - fx;
+
+ }
- /* D3D viewport is integer space. Convert fx,fy,etc. to
- * integers.
- *
- * TODO: adjust pretranslate correct for any subpixel error
- * introduced converting to integers.
- */
- rect.x = fx;
- rect.y = fy;
- rect.w = fw;
- rect.h = fh;
+ if (fy + fh > fb_height) {
+ prescale.scale[1] *= fh / (fb_height - fy);
+ prescale.translate[1] -= fy * (fh / (fb_height - fy));
+ prescale.translate[1] += fy;
+ fh = fb_height - fy;
+ }
- SVGA_DBG(DEBUG_VIEWPORT,
- "viewport error %f,%f %fx%f\n",
- fabs((float)rect.x - fx),
- fabs((float)rect.y - fy),
- fabs((float)rect.w - fw),
- fabs((float)rect.h - fh));
+ if (fw < 0 || fh < 0) {
+ fw = fh = fx = fy = 0;
+ degenerate = TRUE;
+ goto out;
+ }
- SVGA_DBG(DEBUG_VIEWPORT,
- "viewport %d,%d %dx%d\n",
- rect.x,
- rect.y,
- rect.w,
- rect.h);
-
- /* Finally, to get GL rasterization rules, need to tweak the
- * screen-space coordinates slightly relative to D3D which is
- * what hardware implements natively.
- */
- if (svga->curr.rast->templ.gl_rasterization_rules) {
- float adjust_x = 0.0;
- float adjust_y = 0.0;
-
- switch (svga->curr.reduced_prim) {
- case PIPE_PRIM_LINES:
- adjust_x = -0.5;
- adjust_y = 0;
- break;
- case PIPE_PRIM_POINTS:
- case PIPE_PRIM_TRIANGLES:
- adjust_x = -0.375;
- adjust_y = -0.5;
- break;
- }
-
- prescale.translate[0] += adjust_x;
- prescale.translate[1] += adjust_y;
- prescale.translate[2] = 0.5; /* D3D clip space */
- prescale.scale[2] = 0.5; /* D3D clip space */
+ /* D3D viewport is integer space. Convert fx,fy,etc. to
+ * integers.
+ *
+ * TODO: adjust pretranslate correct for any subpixel error
+ * introduced converting to integers.
+ */
+ rect.x = fx;
+ rect.y = fy;
+ rect.w = fw;
+ rect.h = fh;
+
+ SVGA_DBG(DEBUG_VIEWPORT,
+ "viewport error %f,%f %fx%f\n",
+ fabs((float)rect.x - fx),
+ fabs((float)rect.y - fy),
+ fabs((float)rect.w - fw),
+ fabs((float)rect.h - fh));
+
+ SVGA_DBG(DEBUG_VIEWPORT,
+ "viewport %d,%d %dx%d\n",
+ rect.x,
+ rect.y,
+ rect.w,
+ rect.h);
+
+
+ /* Finally, to get GL rasterization rules, need to tweak the
+ * screen-space coordinates slightly relative to D3D which is
+ * what hardware implements natively.
+ */
+ if (svga->curr.rast->templ.gl_rasterization_rules) {
+ float adjust_x = 0.0;
+ float adjust_y = 0.0;
+
+ switch (svga->curr.reduced_prim) {
+ case PIPE_PRIM_LINES:
+ adjust_x = -0.5;
+ adjust_y = 0;
+ break;
+ case PIPE_PRIM_POINTS:
+ case PIPE_PRIM_TRIANGLES:
+ adjust_x = -0.375;
+ adjust_y = -0.5;
+ break;
}
+ prescale.translate[0] += adjust_x;
+ prescale.translate[1] += adjust_y;
+ prescale.translate[2] = 0.5; /* D3D clip space */
+ prescale.scale[2] = 0.5; /* D3D clip space */
+ }
- range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
- range_max = viewport->scale[2] * 1.0 + viewport->translate[2];
- /* D3D (and by implication SVGA) doesn't like dealing with zmax
- * less than zmin. Detect that case, flip the depth range and
- * invert our z-scale factor to achieve the same effect.
- */
- if (range_min > range_max) {
- float range_tmp;
- range_tmp = range_min;
- range_min = range_max;
- range_max = range_tmp;
- prescale.scale[2] = -prescale.scale[2];
- }
+ range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
+ range_max = viewport->scale[2] * 1.0 + viewport->translate[2];
+
+ /* D3D (and by implication SVGA) doesn't like dealing with zmax
+ * less than zmin. Detect that case, flip the depth range and
+ * invert our z-scale factor to achieve the same effect.
+ */
+ if (range_min > range_max) {
+ float range_tmp;
+ range_tmp = range_min;
+ range_min = range_max;
+ range_max = range_tmp;
+ prescale.scale[2] = -prescale.scale[2];
}
if (prescale.enabled) {
/* SVGA_NEW_CLIP
*/
- if (!svga->curr.rast->templ.bypass_vs_clip_and_viewport &&
- svga->curr.clip.nr) {
+ if (svga->curr.clip.nr) {
SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__);
need_pipeline = TRUE;
}
trace_dump_member(uint, state, line_stipple_factor);
trace_dump_member(uint, state, line_stipple_pattern);
trace_dump_member(bool, state, line_last_pixel);
- trace_dump_member(bool, state, bypass_vs_clip_and_viewport);
trace_dump_member(bool, state, flatshade_first);
trace_dump_member(bool, state, gl_rasterization_rules);
unsigned line_stipple_pattern:16;
unsigned line_last_pixel:1;
- /**
- * Vertex coordinates are pre-transformed to screen space. Skip
- * the vertex shader, clipping and viewport processing. Note that
- * a vertex shader is still needed though, to indicate the mapping
- * from vertex elements to fragment shader input semantics.
- *
- * XXX: considered for removal.
- */
- unsigned bypass_vs_clip_and_viewport:1;
-
/**
* Use the first vertex of a primitive as the provoking vertex for
* flat shading.
memset(&st->clear.raster, 0, sizeof(st->clear.raster));
st->clear.raster.gl_rasterization_rules = 1;
- /* rasterizer state: bypass vertex shader, clipping and viewport */
- st->clear.raster.bypass_vs_clip_and_viewport = 1;
-
/* fragment shader state: color pass-through program */
st->clear.fs =
util_make_fragment_passthrough_shader(pipe);
/**
* Draw a screen-aligned quadrilateral.
- * Coords are window coords with y=0=bottom. These will be passed
- * through unmodified to the rasterizer as we have set
- * rasterizer->bypass_vs_clip_and_viewport.
+ * Coords are clip coords with y=0=bottom.
*/
static void
draw_quad(GLcontext *ctx,
GLboolean color, GLboolean depth, GLboolean stencil)
{
struct st_context *st = ctx->st;
- const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
- const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
- GLfloat y0, y1;
-
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
- y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax);
- y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin);
- }
- else {
- y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
- y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
- }
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+ const GLfloat fb_width = (GLfloat) fb->Width;
+ const GLfloat fb_height = (GLfloat) fb->Height;
+ const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
+ const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
+ const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
+ const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
/*
printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
cso_save_stencil_ref(st->cso_context);
cso_save_depth_stencil_alpha(st->cso_context);
cso_save_rasterizer(st->cso_context);
+ cso_save_viewport(st->cso_context);
cso_save_fragment_shader(st->cso_context);
cso_save_vertex_shader(st->cso_context);
cso_set_rasterizer(st->cso_context, &st->clear.raster);
+ /* viewport state: viewport matching window dims */
+ {
+ const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
+ struct pipe_viewport_state vp;
+ vp.scale[0] = 0.5f * fb_width;
+ vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
+ vp.scale[2] = 1.0f;
+ vp.scale[3] = 1.0f;
+ vp.translate[0] = 0.5f * fb_width;
+ vp.translate[1] = 0.5f * fb_height;
+ vp.translate[2] = 0.0f;
+ vp.translate[3] = 0.0f;
+ cso_set_viewport(st->cso_context, &vp);
+ }
+
cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
cso_restore_stencil_ref(st->cso_context);
cso_restore_depth_stencil_alpha(st->cso_context);
cso_restore_rasterizer(st->cso_context);
+ cso_restore_viewport(st->cso_context);
cso_restore_fragment_shader(st->cso_context);
cso_restore_vertex_shader(st->cso_context);
-
}