X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsoftpipe%2Fsp_setup.c;h=6704015112b8eda5607f6530c668343d9b675c60;hb=13862812dc910a4ef57cb72cb9fe777ce3c14515;hp=48f29f87661c7fb13c43527bda56677994ad3e13;hpb=4736c0ba8670637970a971da6ec83cf1d2620a32;p=mesa.git diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 48f29f87661..6704015112b 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,7 +28,7 @@ /** * \brief Primitive rasterization/rendering (points, lines, triangles) * - * \author Keith Whitwell + * \author Keith Whitwell * \author Brian Paul */ @@ -92,6 +92,7 @@ struct setup_context { int facing; float pixel_offset; + unsigned max_layer; struct quad_header quad[MAX_QUADS]; struct quad_header *quad_ptrs[MAX_QUADS]; @@ -163,6 +164,10 @@ clip_emit_quad(struct setup_context *setup, struct quad_header *quad) if (quad->inout.mask) { struct softpipe_context *sp = setup->softpipe; +#if DEBUG_FRAGS + setup->numFragsEmitted += util_bitcount(quad->inout.mask); +#endif + sp->quad.first->run( sp->quad.first, &quad, 1 ); } } @@ -234,6 +239,9 @@ flush_spans(struct setup_context *setup) setup->quad[q].inout.mask = quadmask; setup->quad_ptrs[q] = &setup->quad[q]; q++; +#if DEBUG_FRAGS + setup->numFragsEmitted += util_bitcount(quadmask); +#endif } mask0 >>= 2; mask1 >>= 2; @@ -387,7 +395,7 @@ setup_sort_vertices(struct setup_context *setup, * - pixel center (0.5, 0.5) for GL, or * - assume (0.0, 0.0) for other APIs. */ - if (setup->softpipe->rasterizer->gl_rasterization_rules) { + if (setup->softpipe->rasterizer->half_pixel_center) { setup->pixel_offset = 0.5f; } else { setup->pixel_offset = 0.0f; @@ -504,14 +512,6 @@ tri_linear_coeff(struct setup_context *setup, coef->a0[i] = (v[0] - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + dady * (setup->vmin[0][1] - setup->pixel_offset))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ } @@ -542,13 +542,6 @@ tri_persp_coeff(struct setup_context *setup, float dadx = a * setup->oneoverarea; float dady = b * setup->oneoverarea; - /* - debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, - setup->vmin[vertSlot][i], - setup->vmid[vertSlot][i], - setup->vmax[vertSlot][i] - ); - */ assert(i <= 3); coef->dadx[i] = dadx; @@ -568,17 +561,22 @@ tri_persp_coeff(struct setup_context *setup, static void setup_fragcoord_coeff(struct setup_context *setup, uint slot) { - struct sp_fragment_shader* spfs = setup->softpipe->fs; + const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; + boolean origin_lower_left = + fsInfo->properties[TGSI_PROPERTY_FS_COORD_ORIGIN]; + boolean pixel_center_integer = + fsInfo->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER]; + /*X*/ - setup->coef[slot].a0[0] = spfs->info.pixel_center_integer ? 0.0 : 0.5; - setup->coef[slot].dadx[0] = 1.0; - setup->coef[slot].dady[0] = 0.0; + setup->coef[slot].a0[0] = pixel_center_integer ? 0.0f : 0.5f; + setup->coef[slot].dadx[0] = 1.0f; + setup->coef[slot].dady[0] = 0.0f; /*Y*/ setup->coef[slot].a0[1] = - (spfs->info.origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0) - + (spfs->info.pixel_center_integer ? 0.0 : 0.5); - setup->coef[slot].dadx[1] = 0.0; - setup->coef[slot].dady[1] = spfs->info.origin_lower_left ? -1.0 : 1.0; + (origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0) + + (pixel_center_integer ? 0.0f : 0.5f); + setup->coef[slot].dadx[1] = 0.0f; + setup->coef[slot].dady[1] = origin_lower_left ? -1.0f : 1.0f; /*Z*/ setup->coef[slot].a0[2] = setup->posCoef.a0[2]; setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; @@ -599,7 +597,7 @@ static void setup_tri_coefficients(struct setup_context *setup) { struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; + const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; float v[3]; @@ -618,31 +616,31 @@ setup_tri_coefficients(struct setup_context *setup) /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { const uint vertSlot = vinfo->attrib[fragSlot].src_index; uint j; switch (vinfo->attrib[fragSlot].interp_mode) { case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) + for (j = 0; j < TGSI_NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) { + for (j = 0; j < TGSI_NUM_CHANNELS; j++) { tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmid[vertSlot][j], setup->vmax[vertSlot][j], - spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); tri_linear_coeff(setup, &setup->coef[fragSlot], j, v); } break; case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) { + for (j = 0; j < TGSI_NUM_CHANNELS; j++) { tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmid[vertSlot][j], setup->vmax[vertSlot][j], - spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); tri_persp_coeff(setup, &setup->coef[fragSlot], j, v); } @@ -654,12 +652,22 @@ setup_tri_coefficients(struct setup_context *setup) assert(0); } - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { /* convert 0 to 1.0 and 1 to -1.0 */ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } + + if (0) { + for (j = 0; j < TGSI_NUM_CHANNELS; j++) { + debug_printf("attr[%d].%c: a0:%f dx:%f dy:%f\n", + fragSlot, "xyzw"[j], + setup->coef[fragSlot].a0[j], + setup->coef[fragSlot].dadx[j], + setup->coef[fragSlot].dady[j]); + } + } } } @@ -798,7 +806,7 @@ sp_setup_tri(struct setup_context *setup, const float (*v2)[4]) { float det; - + uint layer = 0; #if DEBUG_VERTS debug_printf("Setup triangle:\n"); print_vertex(setup, v0); @@ -806,7 +814,7 @@ sp_setup_tri(struct setup_context *setup, print_vertex(setup, v2); #endif - if (setup->softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; det = calc_det(v0, v1, v2); @@ -831,6 +839,11 @@ sp_setup_tri(struct setup_context *setup, setup->span.right[0] = 0; setup->span.right[1] = 0; /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ + if (setup->softpipe->layer_slot > 0) { + layer = *(unsigned *)v1[setup->softpipe->layer_slot]; + layer = MIN2(layer, setup->max_layer); + } + setup->quad[0].input.layer = layer; /* init_constant_attribs( setup ); */ @@ -849,6 +862,10 @@ sp_setup_tri(struct setup_context *setup, flush_spans( setup ); + if (setup->softpipe->active_statistics_queries) { + setup->softpipe->pipeline_statistics.c_primitives++; + } + #if DEBUG_FRAGS printf("Tri: %u frags emitted, %u written\n", setup->numFragsEmitted, @@ -939,7 +956,7 @@ setup_line_coefficients(struct setup_context *setup, const float (*v1)[4]) { struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; + const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; float area; @@ -974,29 +991,29 @@ setup_line_coefficients(struct setup_context *setup, /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { const uint vertSlot = vinfo->attrib[fragSlot].src_index; uint j; switch (vinfo->attrib[fragSlot].interp_mode) { case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) + for (j = 0; j < TGSI_NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) { + for (j = 0; j < TGSI_NUM_CHANNELS; j++) { line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmax[vertSlot][j], - spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); line_linear_coeff(setup, &setup->coef[fragSlot], j, v); } break; case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) { + for (j = 0; j < TGSI_NUM_CHANNELS; j++) { line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmax[vertSlot][j], - spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); line_persp_coeff(setup, &setup->coef[fragSlot], j, v); } @@ -1008,7 +1025,7 @@ setup_line_coefficients(struct setup_context *setup, assert(0); } - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { /* convert 0 to 1.0 and 1 to -1.0 */ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; setup->coef[fragSlot].dadx[0] = 0.0; @@ -1065,6 +1082,7 @@ sp_setup_line(struct setup_context *setup, int dx = x1 - x0; int dy = y1 - y0; int xstep, ystep; + uint layer = 0; #if DEBUG_VERTS debug_printf("Setup line:\n"); @@ -1072,7 +1090,7 @@ sp_setup_line(struct setup_context *setup, print_vertex(setup, v1); #endif - if (setup->softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; if (dx == 0 && dy == 0) @@ -1108,6 +1126,11 @@ sp_setup_line(struct setup_context *setup, setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; setup->quad[0].inout.mask = 0x0; + if (setup->softpipe->layer_slot > 0) { + layer = *(unsigned *)v1[setup->softpipe->layer_slot]; + layer = MIN2(layer, setup->max_layer); + } + setup->quad[0].input.layer = layer; /* XXX temporary: set coverage to 1.0 so the line appears * if AA mode happens to be enabled. @@ -1188,7 +1211,7 @@ sp_setup_point(struct setup_context *setup, const float (*v0)[4]) { struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; + const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; const int sizeAttr = setup->softpipe->psize_slot; const float size = sizeAttr > 0 ? v0[sizeAttr][0] @@ -1199,17 +1222,23 @@ sp_setup_point(struct setup_context *setup, const float y = v0[0][1]; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; - + uint layer = 0; #if DEBUG_VERTS debug_printf("Setup point:\n"); print_vertex(setup, v0); #endif - if (softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS); + if (setup->softpipe->layer_slot > 0) { + layer = *(unsigned *)v0[setup->softpipe->layer_slot]; + layer = MIN2(layer, setup->max_layer); + } + setup->quad[0].input.layer = layer; + /* For points, all interpolants are constant-valued. * However, for point sprites, we'll need to setup texcoords appropriately. * XXX: which coefficients are the texcoords??? @@ -1232,7 +1261,7 @@ sp_setup_point(struct setup_context *setup, const_coeff(setup, &setup->posCoef, 0, 2); const_coeff(setup, &setup->posCoef, 0, 3); - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { const uint vertSlot = vinfo->attrib[fragSlot].src_index; uint j; @@ -1240,11 +1269,11 @@ sp_setup_point(struct setup_context *setup, case INTERP_CONSTANT: /* fall-through */ case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) + for (j = 0; j < TGSI_NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) + for (j = 0; j < TGSI_NUM_CHANNELS; j++) point_persp_coeff(setup, setup->vprovoke, &setup->coef[fragSlot], vertSlot, j); break; @@ -1255,7 +1284,7 @@ sp_setup_point(struct setup_context *setup, assert(0); } - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { /* convert 0 to 1.0 and 1 to -1.0 */ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; setup->coef[fragSlot].dadx[0] = 0.0; @@ -1394,14 +1423,32 @@ void sp_setup_prepare(struct setup_context *setup) { struct softpipe_context *sp = setup->softpipe; - + int i; + unsigned max_layer = ~0; if (sp->dirty) { - softpipe_update_derived(sp); + softpipe_update_derived(sp, sp->reduced_api_prim); } /* Note: nr_attrs is only used for debugging (vertex printing) */ setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw); + /* + * Determine how many layers the fb has (used for clamping layer value). + * OpenGL (but not d3d10) permits different amount of layers per rt, however + * results are undefined if layer exceeds the amount of layers of ANY + * attachment hence don't need separate per cbuf and zsbuf max. + */ + for (i = 0; i < setup->softpipe->framebuffer.nr_cbufs; i++) { + struct pipe_surface *cbuf = setup->softpipe->framebuffer.cbufs[i]; + if (cbuf) { + max_layer = MIN2(max_layer, + cbuf->u.tex.last_layer - cbuf->u.tex.first_layer); + + } + } + + setup->max_layer = max_layer; + sp->quad.first->begin( sp->quad.first ); if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&