~ubuntu-branches/ubuntu/raring/xserver-xorg-video-intel/raring

« back to all changes in this revision

Viewing changes to src/sna/gen5_render.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2013-01-08 17:58:48 UTC
  • mfrom: (1.4.28)
  • Revision ID: package-import@ubuntu.com-20130108175848-98g6sbzeepup1kgw
Tags: 2:2.20.17-0ubuntu1
Merge from unreleased debian git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
#include "brw/brw.h"
44
44
#include "gen5_render.h"
 
45
#include "gen4_vertex.h"
45
46
 
 
47
#define NO_COMPOSITE 0
46
48
#define NO_COMPOSITE_SPANS 0
47
49
 
48
50
#define PREFER_BLT_FILL 1
163
165
#define SAMPLER_OFFSET(sf, se, mf, me, k) \
164
166
        ((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * KERNEL_COUNT + (k)) * 64)
165
167
 
 
168
#define VERTEX_2s2s 0
 
169
 
166
170
static bool
167
171
gen5_emit_pipelined_pointers(struct sna *sna,
168
172
                             const struct sna_composite_op *op,
207
211
        assert(sna->render.vertex_index > sna->render.vertex_start);
208
212
 
209
213
        DBG(("%s: CA fixup\n", __FUNCTION__));
 
214
        assert(op->mask.bo != NULL);
 
215
        assert(op->has_component_alpha);
210
216
 
211
217
        gen5_emit_pipelined_pointers
212
218
                (sna, op, PictOpAdd,
227
233
        state->last_primitive = sna->kgem.nbatch;
228
234
}
229
235
 
230
 
static void gen5_vertex_flush(struct sna *sna)
231
 
{
232
 
        assert(sna->render_state.gen5.vertex_offset);
233
 
        assert(sna->render.vertex_index > sna->render.vertex_start);
234
 
 
235
 
        DBG(("%s[%x] = %d\n", __FUNCTION__,
236
 
             4*sna->render_state.gen5.vertex_offset,
237
 
             sna->render.vertex_index - sna->render.vertex_start));
238
 
        sna->kgem.batch[sna->render_state.gen5.vertex_offset] =
239
 
                sna->render.vertex_index - sna->render.vertex_start;
240
 
        sna->render_state.gen5.vertex_offset = 0;
241
 
}
242
 
 
243
 
static int gen5_vertex_finish(struct sna *sna)
244
 
{
245
 
        struct kgem_bo *bo;
246
 
        unsigned int i;
247
 
 
248
 
        assert(sna->render.vertex_used);
249
 
        assert(sna->render.nvertex_reloc);
250
 
 
251
 
        /* Note: we only need dword alignment (currently) */
252
 
 
253
 
        bo = sna->render.vbo;
254
 
        if (bo) {
255
 
                if (sna->render_state.gen5.vertex_offset)
256
 
                        gen5_vertex_flush(sna);
257
 
 
258
 
                for (i = 0; i < sna->render.nvertex_reloc; i++) {
259
 
                        DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
260
 
                             i, sna->render.vertex_reloc[i]));
261
 
 
262
 
                        sna->kgem.batch[sna->render.vertex_reloc[i]] =
263
 
                                kgem_add_reloc(&sna->kgem,
264
 
                                               sna->render.vertex_reloc[i], bo,
265
 
                                               I915_GEM_DOMAIN_VERTEX << 16,
266
 
                                               0);
267
 
                }
268
 
 
269
 
                sna->render.nvertex_reloc = 0;
270
 
                sna->render.vertex_used = 0;
271
 
                sna->render.vertex_index = 0;
272
 
                sna->render.vbo = NULL;
273
 
                sna->render_state.gen5.vb_id = 0;
274
 
 
275
 
                kgem_bo_destroy(&sna->kgem, bo);
276
 
        }
277
 
 
278
 
        sna->render.vertices = NULL;
279
 
        sna->render.vbo = kgem_create_linear(&sna->kgem,
280
 
                                             256*1024, CREATE_GTT_MAP);
281
 
        if (sna->render.vbo)
282
 
                sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
283
 
        if (sna->render.vertices == NULL) {
284
 
                if (sna->render.vbo)
285
 
                        kgem_bo_destroy(&sna->kgem, sna->render.vbo);
286
 
                sna->render.vbo = NULL;
287
 
                return 0;
288
 
        }
289
 
 
290
 
        if (sna->render.vertex_used) {
291
 
                memcpy(sna->render.vertices,
292
 
                       sna->render.vertex_data,
293
 
                       sizeof(float)*sna->render.vertex_used);
294
 
        }
295
 
        sna->render.vertex_size = 64 * 1024 - 1;
296
 
        return sna->render.vertex_size - sna->render.vertex_used;
297
 
}
298
 
 
299
 
static void gen5_vertex_close(struct sna *sna)
300
 
{
301
 
        struct kgem_bo *bo, *free_bo = NULL;
302
 
        unsigned int i, delta = 0;
303
 
 
304
 
        assert(sna->render_state.gen5.vertex_offset == 0);
305
 
        if (!sna->render_state.gen5.vb_id)
306
 
                return;
307
 
 
308
 
        DBG(("%s: used=%d, vbo active? %d\n",
309
 
             __FUNCTION__, sna->render.vertex_used, sna->render.vbo != NULL));
310
 
 
311
 
        bo = sna->render.vbo;
312
 
        if (bo) {
313
 
                if (sna->render.vertex_size - sna->render.vertex_used < 64) {
314
 
                        DBG(("%s: discarding full vbo\n", __FUNCTION__));
315
 
                        sna->render.vbo = NULL;
316
 
                        sna->render.vertices = sna->render.vertex_data;
317
 
                        sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
318
 
                        free_bo = bo;
319
 
                } else if (IS_CPU_MAP(bo->map)) {
320
 
                        DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
321
 
                        sna->render.vertices =
322
 
                                kgem_bo_map__gtt(&sna->kgem, sna->render.vbo);
323
 
                        if (sna->render.vertices == NULL) {
324
 
                                sna->render.vbo = NULL;
325
 
                                sna->render.vertices = sna->render.vertex_data;
326
 
                                sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
327
 
                                free_bo = bo;
328
 
                        }
329
 
                }
330
 
        } else {
331
 
                if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
332
 
                        DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
333
 
                             sna->render.vertex_used, sna->kgem.nbatch));
334
 
                        memcpy(sna->kgem.batch + sna->kgem.nbatch,
335
 
                               sna->render.vertex_data,
336
 
                               sna->render.vertex_used * 4);
337
 
                        delta = sna->kgem.nbatch * 4;
338
 
                        bo = NULL;
339
 
                        sna->kgem.nbatch += sna->render.vertex_used;
340
 
                } else {
341
 
                        bo = kgem_create_linear(&sna->kgem,
342
 
                                                4*sna->render.vertex_used, 0);
343
 
                        if (bo && !kgem_bo_write(&sna->kgem, bo,
344
 
                                                 sna->render.vertex_data,
345
 
                                                 4*sna->render.vertex_used)) {
346
 
                                kgem_bo_destroy(&sna->kgem, bo);
347
 
                                bo = NULL;
348
 
                        }
349
 
                        DBG(("%s: new vbo: %d\n", __FUNCTION__,
350
 
                             sna->render.vertex_used));
351
 
                        free_bo = bo;
352
 
                }
353
 
        }
354
 
 
355
 
        assert(sna->render.nvertex_reloc);
356
 
        for (i = 0; i < sna->render.nvertex_reloc; i++) {
357
 
                DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
358
 
                     i, sna->render.vertex_reloc[i]));
359
 
 
360
 
                sna->kgem.batch[sna->render.vertex_reloc[i]] =
361
 
                        kgem_add_reloc(&sna->kgem,
362
 
                                       sna->render.vertex_reloc[i], bo,
363
 
                                       I915_GEM_DOMAIN_VERTEX << 16,
364
 
                                       delta);
365
 
        }
366
 
        sna->render.nvertex_reloc = 0;
367
 
 
368
 
        if (sna->render.vbo == NULL) {
369
 
                sna->render.vertex_used = 0;
370
 
                sna->render.vertex_index = 0;
371
 
        }
372
 
 
373
 
        if (free_bo)
374
 
                kgem_bo_destroy(&sna->kgem, free_bo);
375
 
}
376
 
 
377
236
static uint32_t gen5_get_blend(int op,
378
237
                               bool has_component_alpha,
379
238
                               uint32_t dst_format)
670
529
        return offset * sizeof(uint32_t);
671
530
}
672
531
 
673
 
fastcall static void
674
 
gen5_emit_composite_primitive_solid(struct sna *sna,
675
 
                                    const struct sna_composite_op *op,
676
 
                                    const struct sna_composite_rectangles *r)
677
 
{
678
 
        float *v;
679
 
        union {
680
 
                struct sna_coordinate p;
681
 
                float f;
682
 
        } dst;
683
 
 
684
 
        v = sna->render.vertices + sna->render.vertex_used;
685
 
        sna->render.vertex_used += 9;
686
 
 
687
 
        dst.p.x = r->dst.x + r->width;
688
 
        dst.p.y = r->dst.y + r->height;
689
 
        v[0] = dst.f;
690
 
        v[1] = 1.;
691
 
        v[2] = 1.;
692
 
 
693
 
        dst.p.x = r->dst.x;
694
 
        v[3] = dst.f;
695
 
        v[4] = 0.;
696
 
        v[5] = 1.;
697
 
 
698
 
        dst.p.y = r->dst.y;
699
 
        v[6] = dst.f;
700
 
        v[7] = 0.;
701
 
        v[8] = 0.;
702
 
}
703
 
 
704
 
fastcall static void
705
 
gen5_emit_composite_primitive_identity_source(struct sna *sna,
706
 
                                              const struct sna_composite_op *op,
707
 
                                              const struct sna_composite_rectangles *r)
708
 
{
709
 
        const float *sf = op->src.scale;
710
 
        float sx, sy, *v;
711
 
        union {
712
 
                struct sna_coordinate p;
713
 
                float f;
714
 
        } dst;
715
 
 
716
 
        v = sna->render.vertices + sna->render.vertex_used;
717
 
        sna->render.vertex_used += 9;
718
 
 
719
 
        sx = r->src.x + op->src.offset[0];
720
 
        sy = r->src.y + op->src.offset[1];
721
 
 
722
 
        dst.p.x = r->dst.x + r->width;
723
 
        dst.p.y = r->dst.y + r->height;
724
 
        v[0] = dst.f;
725
 
        v[1] = (sx + r->width) * sf[0];
726
 
        v[5] = v[2] = (sy + r->height) * sf[1];
727
 
 
728
 
        dst.p.x = r->dst.x;
729
 
        v[3] = dst.f;
730
 
        v[7] = v[4] = sx * sf[0];
731
 
 
732
 
        dst.p.y = r->dst.y;
733
 
        v[6] = dst.f;
734
 
        v[8] = sy * sf[1];
735
 
}
736
 
 
737
 
fastcall static void
738
 
gen5_emit_composite_primitive_affine_source(struct sna *sna,
739
 
                                            const struct sna_composite_op *op,
740
 
                                            const struct sna_composite_rectangles *r)
741
 
{
742
 
        union {
743
 
                struct sna_coordinate p;
744
 
                float f;
745
 
        } dst;
746
 
        float *v;
747
 
 
748
 
        v = sna->render.vertices + sna->render.vertex_used;
749
 
        sna->render.vertex_used += 9;
750
 
 
751
 
        dst.p.x = r->dst.x + r->width;
752
 
        dst.p.y = r->dst.y + r->height;
753
 
        v[0] = dst.f;
754
 
        _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
755
 
                                         op->src.offset[1] + r->src.y + r->height,
756
 
                                         op->src.transform,
757
 
                                         &v[1], &v[2]);
758
 
        v[1] *= op->src.scale[0];
759
 
        v[2] *= op->src.scale[1];
760
 
 
761
 
        dst.p.x = r->dst.x;
762
 
        v[3] = dst.f;
763
 
        _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
764
 
                                         op->src.offset[1] + r->src.y + r->height,
765
 
                                         op->src.transform,
766
 
                                         &v[4], &v[5]);
767
 
        v[4] *= op->src.scale[0];
768
 
        v[5] *= op->src.scale[1];
769
 
 
770
 
        dst.p.y = r->dst.y;
771
 
        v[6] = dst.f;
772
 
        _sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
773
 
                                         op->src.offset[1] + r->src.y,
774
 
                                         op->src.transform,
775
 
                                         &v[7], &v[8]);
776
 
        v[7] *= op->src.scale[0];
777
 
        v[8] *= op->src.scale[1];
778
 
}
779
 
 
780
 
fastcall static void
781
 
gen5_emit_composite_primitive_identity_mask(struct sna *sna,
782
 
                                            const struct sna_composite_op *op,
783
 
                                            const struct sna_composite_rectangles *r)
784
 
{
785
 
        union {
786
 
                struct sna_coordinate p;
787
 
                float f;
788
 
        } dst;
789
 
        float msk_x, msk_y;
790
 
        float w, h;
791
 
        float *v;
792
 
 
793
 
        msk_x = r->mask.x + op->mask.offset[0];
794
 
        msk_y = r->mask.y + op->mask.offset[1];
795
 
        w = r->width;
796
 
        h = r->height;
797
 
 
798
 
        v = sna->render.vertices + sna->render.vertex_used;
799
 
        sna->render.vertex_used += 15;
800
 
 
801
 
        dst.p.x = r->dst.x + r->width;
802
 
        dst.p.y = r->dst.y + r->height;
803
 
        v[0] = dst.f;
804
 
        v[3] = (msk_x + w) * op->mask.scale[0];
805
 
        v[9] = v[4] = (msk_y + h) * op->mask.scale[1];
806
 
 
807
 
        dst.p.x = r->dst.x;
808
 
        v[5] = dst.f;
809
 
        v[13] = v[8] = msk_x * op->mask.scale[0];
810
 
 
811
 
        dst.p.y = r->dst.y;
812
 
        v[10] = dst.f;
813
 
        v[14] = msk_y * op->mask.scale[1];
814
 
 
815
 
        v[7] = v[2] = v[1] = 1;
816
 
        v[12] = v[11] = v[6] = 0;
817
 
}
818
 
 
819
 
fastcall static void
820
 
gen5_emit_composite_primitive_identity_source_mask(struct sna *sna,
821
 
                                                   const struct sna_composite_op *op,
822
 
                                                   const struct sna_composite_rectangles *r)
823
 
{
824
 
        union {
825
 
                struct sna_coordinate p;
826
 
                float f;
827
 
        } dst;
828
 
        float src_x, src_y;
829
 
        float msk_x, msk_y;
830
 
        float w, h;
831
 
        float *v;
832
 
 
833
 
        src_x = r->src.x + op->src.offset[0];
834
 
        src_y = r->src.y + op->src.offset[1];
835
 
        msk_x = r->mask.x + op->mask.offset[0];
836
 
        msk_y = r->mask.y + op->mask.offset[1];
837
 
        w = r->width;
838
 
        h = r->height;
839
 
 
840
 
        v = sna->render.vertices + sna->render.vertex_used;
841
 
        sna->render.vertex_used += 15;
842
 
 
843
 
        dst.p.x = r->dst.x + r->width;
844
 
        dst.p.y = r->dst.y + r->height;
845
 
        v[0] = dst.f;
846
 
        v[1] = (src_x + w) * op->src.scale[0];
847
 
        v[2] = (src_y + h) * op->src.scale[1];
848
 
        v[3] = (msk_x + w) * op->mask.scale[0];
849
 
        v[4] = (msk_y + h) * op->mask.scale[1];
850
 
 
851
 
        dst.p.x = r->dst.x;
852
 
        v[5] = dst.f;
853
 
        v[6] = src_x * op->src.scale[0];
854
 
        v[7] = v[2];
855
 
        v[8] = msk_x * op->mask.scale[0];
856
 
        v[9] = v[4];
857
 
 
858
 
        dst.p.y = r->dst.y;
859
 
        v[10] = dst.f;
860
 
        v[11] = v[6];
861
 
        v[12] = src_y * op->src.scale[1];
862
 
        v[13] = v[8];
863
 
        v[14] = msk_y * op->mask.scale[1];
864
 
}
865
 
 
866
 
fastcall static void
867
 
gen5_emit_composite_primitive(struct sna *sna,
868
 
                              const struct sna_composite_op *op,
869
 
                              const struct sna_composite_rectangles *r)
870
 
{
871
 
        float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
872
 
        bool is_affine = op->is_affine;
873
 
        const float *src_sf = op->src.scale;
874
 
        const float *mask_sf = op->mask.scale;
875
 
 
876
 
        if (op->src.is_solid) {
877
 
                src_x[0] = 0;
878
 
                src_y[0] = 0;
879
 
                src_x[1] = 0;
880
 
                src_y[1] = 1;
881
 
                src_x[2] = 1;
882
 
                src_y[2] = 1;
883
 
                src_w[0] = src_w[1] = src_w[2] = 1;
884
 
        } else if (is_affine) {
885
 
                sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
886
 
                                                r->src.y + op->src.offset[1],
887
 
                                                op->src.transform,
888
 
                                                &src_x[0],
889
 
                                                &src_y[0]);
890
 
 
891
 
                sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
892
 
                                                r->src.y + op->src.offset[1] + r->height,
893
 
                                                op->src.transform,
894
 
                                                &src_x[1],
895
 
                                                &src_y[1]);
896
 
 
897
 
                sna_get_transformed_coordinates(r->src.x + op->src.offset[0] + r->width,
898
 
                                                r->src.y + op->src.offset[1] + r->height,
899
 
                                                op->src.transform,
900
 
                                                &src_x[2],
901
 
                                                &src_y[2]);
902
 
        } else {
903
 
                sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
904
 
                                                   r->src.y + op->src.offset[1],
905
 
                                                   op->src.transform,
906
 
                                                   &src_x[0],
907
 
                                                   &src_y[0],
908
 
                                                   &src_w[0]);
909
 
                sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
910
 
                                                   r->src.y + op->src.offset[1] + r->height,
911
 
                                                   op->src.transform,
912
 
                                                   &src_x[1],
913
 
                                                   &src_y[1],
914
 
                                                   &src_w[1]);
915
 
                sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0] + r->width,
916
 
                                                   r->src.y + op->src.offset[1] + r->height,
917
 
                                                   op->src.transform,
918
 
                                                   &src_x[2],
919
 
                                                   &src_y[2],
920
 
                                                   &src_w[2]);
921
 
        }
922
 
 
923
 
        if (op->mask.bo) {
924
 
                if (op->mask.is_solid) {
925
 
                        mask_x[0] = 0;
926
 
                        mask_y[0] = 0;
927
 
                        mask_x[1] = 0;
928
 
                        mask_y[1] = 1;
929
 
                        mask_x[2] = 1;
930
 
                        mask_y[2] = 1;
931
 
                        mask_w[0] = mask_w[1] = mask_w[2] = 1;
932
 
                } else if (is_affine) {
933
 
                        sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
934
 
                                                        r->mask.y + op->mask.offset[1],
935
 
                                                        op->mask.transform,
936
 
                                                        &mask_x[0],
937
 
                                                        &mask_y[0]);
938
 
 
939
 
                        sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
940
 
                                                        r->mask.y + op->mask.offset[1] + r->height,
941
 
                                                        op->mask.transform,
942
 
                                                        &mask_x[1],
943
 
                                                        &mask_y[1]);
944
 
 
945
 
                        sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0] + r->width,
946
 
                                                        r->mask.y + op->mask.offset[1] + r->height,
947
 
                                                        op->mask.transform,
948
 
                                                        &mask_x[2],
949
 
                                                        &mask_y[2]);
950
 
                } else {
951
 
                        sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
952
 
                                                           r->mask.y + op->mask.offset[1],
953
 
                                                           op->mask.transform,
954
 
                                                           &mask_x[0],
955
 
                                                           &mask_y[0],
956
 
                                                           &mask_w[0]);
957
 
 
958
 
                        sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
959
 
                                                           r->mask.y + op->mask.offset[1] + r->height,
960
 
                                                           op->mask.transform,
961
 
                                                           &mask_x[1],
962
 
                                                           &mask_y[1],
963
 
                                                           &mask_w[1]);
964
 
                        sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0] + r->width,
965
 
                                                           r->mask.y + op->mask.offset[1] + r->height,
966
 
                                                           op->mask.transform,
967
 
                                                           &mask_x[2],
968
 
                                                           &mask_y[2],
969
 
                                                           &mask_w[2]);
970
 
                }
971
 
        }
972
 
 
973
 
        OUT_VERTEX(r->dst.x + r->width, r->dst.y + r->height);
974
 
        OUT_VERTEX_F(src_x[2] * src_sf[0]);
975
 
        OUT_VERTEX_F(src_y[2] * src_sf[1]);
976
 
        if (!is_affine)
977
 
                OUT_VERTEX_F(src_w[2]);
978
 
        if (op->mask.bo) {
979
 
                OUT_VERTEX_F(mask_x[2] * mask_sf[0]);
980
 
                OUT_VERTEX_F(mask_y[2] * mask_sf[1]);
981
 
                if (!is_affine)
982
 
                        OUT_VERTEX_F(mask_w[2]);
983
 
        }
984
 
 
985
 
        OUT_VERTEX(r->dst.x, r->dst.y + r->height);
986
 
        OUT_VERTEX_F(src_x[1] * src_sf[0]);
987
 
        OUT_VERTEX_F(src_y[1] * src_sf[1]);
988
 
        if (!is_affine)
989
 
                OUT_VERTEX_F(src_w[1]);
990
 
        if (op->mask.bo) {
991
 
                OUT_VERTEX_F(mask_x[1] * mask_sf[0]);
992
 
                OUT_VERTEX_F(mask_y[1] * mask_sf[1]);
993
 
                if (!is_affine)
994
 
                        OUT_VERTEX_F(mask_w[1]);
995
 
        }
996
 
 
997
 
        OUT_VERTEX(r->dst.x, r->dst.y);
998
 
        OUT_VERTEX_F(src_x[0] * src_sf[0]);
999
 
        OUT_VERTEX_F(src_y[0] * src_sf[1]);
1000
 
        if (!is_affine)
1001
 
                OUT_VERTEX_F(src_w[0]);
1002
 
        if (op->mask.bo) {
1003
 
                OUT_VERTEX_F(mask_x[0] * mask_sf[0]);
1004
 
                OUT_VERTEX_F(mask_y[0] * mask_sf[1]);
1005
 
                if (!is_affine)
1006
 
                        OUT_VERTEX_F(mask_w[0]);
1007
 
        }
1008
 
}
1009
 
 
1010
532
static void gen5_emit_vertex_buffer(struct sna *sna,
1011
533
                                    const struct sna_composite_op *op)
1012
534
{
1013
535
        int id = op->u.gen5.ve_id;
1014
536
 
1015
 
        assert((unsigned)id <= 3);
 
537
        assert((sna->render.vb_id & (1 << id)) == 0);
1016
538
 
1017
539
        OUT_BATCH(GEN5_3DSTATE_VERTEX_BUFFERS | 3);
1018
 
        OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA |
 
540
        OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
1019
541
                  (4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
 
542
        assert(sna->render.nvertex_reloc < ARRAY_SIZE(sna->render.vertex_reloc));
1020
543
        sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
1021
544
        OUT_BATCH(0);
1022
545
        OUT_BATCH(~0); /* max address: disabled */
1023
546
        OUT_BATCH(0);
1024
547
 
1025
 
        sna->render_state.gen5.vb_id |= 1 << id;
 
548
        sna->render.vb_id |= 1 << id;
1026
549
}
1027
550
 
1028
551
static void gen5_emit_primitive(struct sna *sna)
1029
552
{
1030
553
        if (sna->kgem.nbatch == sna->render_state.gen5.last_primitive) {
1031
 
                sna->render_state.gen5.vertex_offset = sna->kgem.nbatch - 5;
 
554
                sna->render.vertex_offset = sna->kgem.nbatch - 5;
1032
555
                return;
1033
556
        }
1034
557
 
1037
560
                  (_3DPRIM_RECTLIST << GEN5_3DPRIMITIVE_TOPOLOGY_SHIFT) |
1038
561
                  (0 << 9) |
1039
562
                  4);
1040
 
        sna->render_state.gen5.vertex_offset = sna->kgem.nbatch;
 
563
        sna->render.vertex_offset = sna->kgem.nbatch;
1041
564
        OUT_BATCH(0);   /* vertex count, to be filled in later */
1042
565
        OUT_BATCH(sna->render.vertex_index);
1043
566
        OUT_BATCH(1);   /* single instance */
1054
577
        int id = op->u.gen5.ve_id;
1055
578
        int ndwords;
1056
579
 
1057
 
        assert((unsigned)id <= 3);
1058
 
 
1059
580
        ndwords = op->need_magic_ca_pass ? 20 : 6;
1060
 
        if ((sna->render_state.gen5.vb_id & (1 << id)) == 0)
 
581
        if ((sna->render.vb_id & (1 << id)) == 0)
1061
582
                ndwords += 5;
1062
583
 
1063
584
        if (!kgem_check_batch(&sna->kgem, ndwords))
1064
585
                return false;
1065
586
 
1066
 
        if ((sna->render_state.gen5.vb_id & (1 << id)) == 0)
 
587
        if ((sna->render.vb_id & (1 << id)) == 0)
1067
588
                gen5_emit_vertex_buffer(sna, op);
1068
 
        if (sna->render_state.gen5.vertex_offset == 0)
 
589
        if (sna->render.vertex_offset == 0)
1069
590
                gen5_emit_primitive(sna);
1070
591
 
1071
592
        return true;
1076
597
{
1077
598
        if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 20 : 6))
1078
599
                return 0;
1079
 
        if (!kgem_check_exec(&sna->kgem, 1))
1080
 
                return 0;
1081
 
        if (!kgem_check_reloc(&sna->kgem, 2))
 
600
        if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
1082
601
                return 0;
1083
602
 
1084
603
        if (op->need_magic_ca_pass && sna->render.vbo)
1085
604
                return 0;
1086
605
 
1087
 
        return gen5_vertex_finish(sna);
 
606
        return gen4_vertex_finish(sna);
1088
607
}
1089
608
 
1090
609
inline static int gen5_get_rectangles(struct sna *sna,
1105
624
                        goto flush;
1106
625
        }
1107
626
 
1108
 
        if (unlikely(sna->render_state.gen5.vertex_offset == 0 &&
 
627
        if (unlikely(sna->render.vertex_offset == 0 &&
1109
628
                     !gen5_rectangle_begin(sna, op)))
1110
629
                goto flush;
1111
630
 
1112
 
        if (want * op->floats_per_rect > rem)
 
631
        if (want > 1 && want * op->floats_per_rect > rem)
1113
632
                want = rem / op->floats_per_rect;
1114
633
 
1115
634
        sna->render.vertex_index += 3*want;
1116
635
        return want;
1117
636
 
1118
637
flush:
1119
 
        if (sna->render_state.gen5.vertex_offset) {
1120
 
                gen5_vertex_flush(sna);
 
638
        if (sna->render.vertex_offset) {
 
639
                gen4_vertex_flush(sna);
1121
640
                gen5_magic_ca_pass(sna, op);
1122
641
        }
1123
642
        _kgem_submit(&sna->kgem);
1129
648
gen5_composite_get_binding_table(struct sna *sna,
1130
649
                                 uint16_t *offset)
1131
650
{
1132
 
        uint32_t *table;
1133
 
 
1134
651
        sna->kgem.surface -=
1135
652
                sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t);
 
653
 
 
654
        DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
 
655
 
1136
656
        /* Clear all surplus entries to zero in case of prefetch */
1137
 
        table = memset(sna->kgem.batch + sna->kgem.surface,
1138
 
                       0, sizeof(struct gen5_surface_state_padded));
1139
657
        *offset = sna->kgem.surface;
1140
 
 
1141
 
        DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
1142
 
 
1143
 
        return table;
 
658
        return memset(sna->kgem.batch + sna->kgem.surface,
 
659
                      0, sizeof(struct gen5_surface_state_padded));
1144
660
}
1145
661
 
1146
662
static void
1246
762
static void
1247
763
gen5_align_vertex(struct sna *sna, const struct sna_composite_op *op)
1248
764
{
 
765
        assert(op->floats_per_rect == 3*op->floats_per_vertex);
1249
766
        if (op->floats_per_vertex != sna->render_state.gen5.floats_per_vertex) {
1250
767
                if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
1251
 
                        gen5_vertex_finish(sna);
 
768
                        gen4_vertex_finish(sna);
1252
769
 
1253
770
                DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
1254
771
                     sna->render_state.gen5.floats_per_vertex,
1285
802
                             const struct sna_composite_op *op,
1286
803
                             int blend, int kernel)
1287
804
{
1288
 
        uint16_t offset = sna->kgem.nbatch, last;
 
805
        uint16_t sp, bp;
 
806
        uint32_t key;
 
807
 
 
808
        DBG(("%s: has_mask=%d, src=(%d, %d), mask=(%d, %d),kernel=%d, blend=%d, ca=%d, format=%x\n",
 
809
             __FUNCTION__, op->u.gen4.ve_id & 2,
 
810
             op->src.filter, op->src.repeat,
 
811
             op->mask.filter, op->mask.repeat,
 
812
             kernel, blend, op->has_component_alpha, (int)op->dst.format));
 
813
 
 
814
        sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat,
 
815
                            op->mask.filter, op->mask.repeat,
 
816
                            kernel);
 
817
        bp = gen5_get_blend(blend, op->has_component_alpha, op->dst.format);
 
818
 
 
819
        DBG(("%s: sp=%d, bp=%d\n", __FUNCTION__, sp, bp));
 
820
        key = sp | (uint32_t)bp << 16 | (op->mask.bo != NULL) << 31;
 
821
        if (key == sna->render_state.gen5.last_pipelined_pointers)
 
822
                return false;
 
823
 
1289
824
 
1290
825
        OUT_BATCH(GEN5_3DSTATE_PIPELINED_POINTERS | 5);
1291
826
        OUT_BATCH(sna->render_state.gen5.vs);
1292
827
        OUT_BATCH(GEN5_GS_DISABLE); /* passthrough */
1293
828
        OUT_BATCH(GEN5_CLIP_DISABLE); /* passthrough */
1294
829
        OUT_BATCH(sna->render_state.gen5.sf[op->mask.bo != NULL]);
1295
 
        OUT_BATCH(sna->render_state.gen5.wm +
1296
 
                  SAMPLER_OFFSET(op->src.filter, op->src.repeat,
1297
 
                                 op->mask.filter, op->mask.repeat,
1298
 
                                 kernel));
1299
 
        OUT_BATCH(sna->render_state.gen5.cc +
1300
 
                  gen5_get_blend(blend, op->has_component_alpha, op->dst.format));
 
830
        OUT_BATCH(sna->render_state.gen5.wm + sp);
 
831
        OUT_BATCH(sna->render_state.gen5.cc + bp);
1301
832
 
1302
 
        last = sna->render_state.gen5.last_pipelined_pointers;
1303
 
        if (!DBG_NO_STATE_CACHE && last &&
1304
 
            sna->kgem.batch[offset + 1] == sna->kgem.batch[last + 1] &&
1305
 
            sna->kgem.batch[offset + 3] == sna->kgem.batch[last + 3] &&
1306
 
            sna->kgem.batch[offset + 4] == sna->kgem.batch[last + 4] &&
1307
 
            sna->kgem.batch[offset + 5] == sna->kgem.batch[last + 5] &&
1308
 
            sna->kgem.batch[offset + 6] == sna->kgem.batch[last + 6]) {
1309
 
                sna->kgem.nbatch = offset;
1310
 
                return false;
1311
 
        } else {
1312
 
                sna->render_state.gen5.last_pipelined_pointers = offset;
1313
 
                return true;
1314
 
        }
 
833
        sna->render_state.gen5.last_pipelined_pointers = key;
 
834
        return true;
1315
835
}
1316
836
 
1317
837
static void
1348
868
         *    texture coordinate 1 if (has_mask is true): same as above
1349
869
         */
1350
870
        struct gen5_render_state *render = &sna->render_state.gen5;
1351
 
        bool has_mask = op->mask.bo != NULL;
1352
 
        bool is_affine = op->is_affine;
1353
 
        int nelem = has_mask ? 2 : 1;
1354
 
        int selem = is_affine ? 2 : 3;
1355
 
        uint32_t w_component;
1356
 
        uint32_t src_format;
1357
871
        int id = op->u.gen5.ve_id;
 
872
        bool has_mask = id >> 2;
 
873
        uint32_t format, dw;
 
874
        int offset;
1358
875
 
1359
 
        assert((unsigned)id <= 3);
1360
876
        if (!DBG_NO_STATE_CACHE && render->ve_id == id)
1361
877
                return;
1362
878
 
 
879
        DBG(("%s: changing %d -> %d\n", __FUNCTION__, render->ve_id, id));
1363
880
        render->ve_id = id;
1364
881
 
1365
 
        if (is_affine) {
1366
 
                src_format = GEN5_SURFACEFORMAT_R32G32_FLOAT;
1367
 
                w_component = GEN5_VFCOMPONENT_STORE_1_FLT;
1368
 
        } else {
1369
 
                src_format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT;
1370
 
                w_component = GEN5_VFCOMPONENT_STORE_SRC;
 
882
        if (id == VERTEX_2s2s) {
 
883
                DBG(("%s: setup COPY\n", __FUNCTION__));
 
884
                assert(op->floats_per_rect == 6);
 
885
 
 
886
                OUT_BATCH(GEN5_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + 2)) + 1 - 2));
 
887
 
 
888
                OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
889
                          GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
 
890
                          0 << VE0_OFFSET_SHIFT);
 
891
                OUT_BATCH(VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
 
892
                          VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
 
893
                          VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
 
894
                          VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
 
895
 
 
896
                /* x,y */
 
897
                OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
898
                          GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
 
899
                          0 << VE0_OFFSET_SHIFT);
 
900
                OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
 
901
                          VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
 
902
                          VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
 
903
                          VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
 
904
 
 
905
                /* s,t */
 
906
                OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
907
                          GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
 
908
                          4 << VE0_OFFSET_SHIFT);
 
909
                OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
 
910
                          VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
 
911
                          VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
 
912
                          VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
 
913
                return;
1371
914
        }
1372
915
 
1373
916
        /* The VUE layout
1379
922
         * dword 4-15 are fetched from vertex buffer
1380
923
         */
1381
924
        OUT_BATCH(GEN5_3DSTATE_VERTEX_ELEMENTS |
1382
 
                ((2 * (2 + nelem)) + 1 - 2));
 
925
                ((2 * (has_mask ? 4 : 3)) + 1 - 2));
1383
926
 
1384
927
        OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1385
928
                  (GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT) |
1386
929
                  (0 << VE0_OFFSET_SHIFT));
1387
 
        OUT_BATCH((GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
1388
 
                  (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
1389
 
                  (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
1390
 
                  (GEN5_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
 
930
        OUT_BATCH((VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
 
931
                  (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
 
932
                  (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
 
933
                  (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
1391
934
 
1392
935
        /* x,y */
1393
 
        OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1394
 
                  (GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT) |
1395
 
                  (0 << VE0_OFFSET_SHIFT)); /* offsets vb in bytes */
1396
 
        OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1397
 
                  (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1398
 
                  (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1399
 
                  (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
 
936
        OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
937
                  GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
 
938
                  0 << VE0_OFFSET_SHIFT);
 
939
        OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
 
940
                  VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
 
941
                  VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
 
942
                  VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
 
943
        offset = 4;
1400
944
 
1401
945
        /* u0, v0, w0 */
1402
 
        OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1403
 
                  (src_format << VE0_FORMAT_SHIFT) |
1404
 
                  (4 << VE0_OFFSET_SHIFT));     /* offset vb in bytes */
1405
 
        OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1406
 
                  (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1407
 
                  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1408
 
                  (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
 
946
        DBG(("%s: id=%d, first channel %d floats, offset=%d\n", __FUNCTION__,
 
947
             id, id & 3, offset));
 
948
        dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
 
949
        switch (id & 3) {
 
950
        case 1:
 
951
                format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT;
 
952
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
953
                dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
 
954
                dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
 
955
                break;
 
956
        default:
 
957
                assert(0);
 
958
        case 2:
 
959
                format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT;
 
960
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
961
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
 
962
                dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
 
963
                break;
 
964
        case 3:
 
965
                format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT;
 
966
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
967
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
 
968
                dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
 
969
                break;
 
970
        }
 
971
        OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
972
                  format | offset << VE0_OFFSET_SHIFT);
 
973
        OUT_BATCH(dw);
1409
974
 
1410
975
        /* u1, v1, w1 */
1411
976
        if (has_mask) {
1412
 
                OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1413
 
                          (src_format << VE0_FORMAT_SHIFT) |
1414
 
                          (((1 + selem) * 4) << VE0_OFFSET_SHIFT)); /* vb offset in bytes */
1415
 
                OUT_BATCH((GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1416
 
                          (GEN5_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1417
 
                          (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1418
 
                          (GEN5_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
 
977
                offset += (id & 3) * sizeof(float);
 
978
                DBG(("%s: id=%x, second channel %d floats, offset=%d\n", __FUNCTION__,
 
979
                     id, (id >> 2) & 3, offset));
 
980
                dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT;
 
981
                switch ((id >> 2) & 3) {
 
982
                case 1:
 
983
                        format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT;
 
984
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
985
                        dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT;
 
986
                        dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
 
987
                        break;
 
988
                default:
 
989
                        assert(0);
 
990
                case 2:
 
991
                        format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT;
 
992
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
993
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
 
994
                        dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT;
 
995
                        break;
 
996
                case 3:
 
997
                        format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT;
 
998
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT;
 
999
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT;
 
1000
                        dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT;
 
1001
                        break;
 
1002
                }
 
1003
                OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
 
1004
                          format | offset << VE0_OFFSET_SHIFT);
 
1005
                OUT_BATCH(dw);
1419
1006
        }
1420
1007
}
1421
1008
 
1461
1048
                             op->src.bo, op->src.width, op->src.height,
1462
1049
                             op->src.card_format,
1463
1050
                             false);
1464
 
        if (op->mask.bo)
 
1051
        if (op->mask.bo) {
 
1052
                assert(op->u.gen4.ve_id >> 2);
1465
1053
                binding_table[2] =
1466
1054
                        gen5_bind_bo(sna,
1467
1055
                                     op->mask.bo,
1469
1057
                                     op->mask.height,
1470
1058
                                     op->mask.card_format,
1471
1059
                                     false);
 
1060
        }
1472
1061
 
1473
1062
        if (sna->kgem.surface == offset &&
1474
1063
            *(uint64_t *)(sna->kgem.batch + sna->render_state.gen5.surface_table) == *(uint64_t*)binding_table &&
1601
1190
        int src_height[6];
1602
1191
        int src_pitch[6];
1603
1192
        uint32_t *binding_table;
 
1193
        uint16_t offset;
1604
1194
        int n_src, n;
1605
 
        uint16_t offset;
1606
 
 
1607
1195
 
1608
1196
        src_surf_base[0] = 0;
1609
1197
        src_surf_base[1] = 0;
1637
1225
        }
1638
1226
 
1639
1227
        gen5_get_batch(sna, op);
 
1228
 
1640
1229
        binding_table = gen5_composite_get_binding_table(sna, &offset);
1641
 
 
1642
1230
        binding_table[0] =
1643
1231
                gen5_bind_bo(sna,
1644
1232
                             op->dst.bo, op->dst.width, op->dst.height,
1665
1253
                  RegionPtr dstRegion,
1666
1254
                  short src_w, short src_h,
1667
1255
                  short drw_w, short drw_h,
 
1256
                  short dx, short dy,
1668
1257
                  PixmapPtr pixmap)
1669
1258
{
1670
1259
        struct sna_composite_op tmp;
1671
 
        int nbox, dxo, dyo, pix_xoff, pix_yoff;
 
1260
        int nbox, pix_xoff, pix_yoff;
1672
1261
        float src_scale_x, src_scale_y;
1673
1262
        struct sna_pixmap *priv;
1674
1263
        BoxPtr box;
1697
1286
        tmp.mask.bo = NULL;
1698
1287
        tmp.u.gen5.wm_kernel =
1699
1288
                is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED;
1700
 
        tmp.u.gen5.ve_id = 1;
 
1289
        tmp.u.gen5.ve_id = 2;
1701
1290
        tmp.is_affine = true;
1702
1291
        tmp.floats_per_vertex = 3;
1703
1292
        tmp.floats_per_rect = 9;
1722
1311
        pix_yoff = 0;
1723
1312
#endif
1724
1313
 
1725
 
        dxo = dstRegion->extents.x1;
1726
 
        dyo = dstRegion->extents.y1;
1727
 
 
1728
1314
        /* Use normalized texture coordinates */
1729
1315
        src_scale_x = ((float)src_w / frame->width) / (float)drw_w;
1730
1316
        src_scale_y = ((float)src_h / frame->height) / (float)drw_h;
1742
1328
                gen5_get_rectangles(sna, &tmp, 1, gen5_video_bind_surfaces);
1743
1329
 
1744
1330
                OUT_VERTEX(r.x2, r.y2);
1745
 
                OUT_VERTEX_F((box->x2 - dxo) * src_scale_x);
1746
 
                OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
 
1331
                OUT_VERTEX_F((box->x2 - dx) * src_scale_x);
 
1332
                OUT_VERTEX_F((box->y2 - dy) * src_scale_y);
1747
1333
 
1748
1334
                OUT_VERTEX(r.x1, r.y2);
1749
 
                OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
1750
 
                OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
 
1335
                OUT_VERTEX_F((box->x1 - dx) * src_scale_x);
 
1336
                OUT_VERTEX_F((box->y2 - dy) * src_scale_y);
1751
1337
 
1752
1338
                OUT_VERTEX(r.x1, r.y1);
1753
 
                OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
1754
 
                OUT_VERTEX_F((box->y1 - dyo) * src_scale_y);
 
1339
                OUT_VERTEX_F((box->x1 - dx) * src_scale_x);
 
1340
                OUT_VERTEX_F((box->y1 - dy) * src_scale_y);
1755
1341
 
1756
1342
                if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
1757
1343
                        sna_damage_add_box(&priv->gpu_damage, &r);
1761
1347
        }
1762
1348
        priv->clear = false;
1763
1349
 
1764
 
        gen5_vertex_flush(sna);
 
1350
        gen4_vertex_flush(sna);
1765
1351
        return true;
1766
1352
}
1767
1353
 
1768
 
static int
 
1354
static bool
1769
1355
gen5_composite_solid_init(struct sna *sna,
1770
1356
                          struct sna_composite_channel *channel,
1771
1357
                          uint32_t color)
2003
1589
gen5_render_composite_done(struct sna *sna,
2004
1590
                           const struct sna_composite_op *op)
2005
1591
{
2006
 
        if (sna->render_state.gen5.vertex_offset) {
2007
 
                gen5_vertex_flush(sna);
 
1592
        if (sna->render.vertex_offset) {
 
1593
                gen4_vertex_flush(sna);
2008
1594
                gen5_magic_ca_pass(sna,op);
2009
1595
        }
2010
1596
 
2027
1613
        BoxRec box;
2028
1614
 
2029
1615
        op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
 
1616
        op->dst.width  = op->dst.pixmap->drawable.width;
 
1617
        op->dst.height = op->dst.pixmap->drawable.height;
2030
1618
        op->dst.format = dst->format;
2031
 
        op->dst.width = op->dst.pixmap->drawable.width;
2032
 
        op->dst.height = op->dst.pixmap->drawable.height;
2033
 
 
2034
1619
        if (w && h) {
2035
1620
                box.x1 = x;
2036
1621
                box.y1 = y;
2390
1975
        tmp->has_component_alpha = false;
2391
1976
        tmp->need_magic_ca_pass = false;
2392
1977
 
2393
 
        tmp->prim_emit = gen5_emit_composite_primitive;
2394
1978
        if (mask) {
2395
1979
                if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
2396
1980
                        tmp->has_component_alpha = true;
2434
2018
                }
2435
2019
 
2436
2020
                tmp->is_affine &= tmp->mask.is_affine;
2437
 
 
2438
 
                if (tmp->src.transform == NULL && tmp->mask.transform == NULL) {
2439
 
                        if (tmp->src.is_solid)
2440
 
                                tmp->prim_emit = gen5_emit_composite_primitive_identity_mask;
2441
 
                        else
2442
 
                                tmp->prim_emit = gen5_emit_composite_primitive_identity_source_mask;
2443
 
                }
2444
 
 
2445
 
                tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
2446
 
        } else {
2447
 
                if (tmp->src.is_solid)
2448
 
                        tmp->prim_emit = gen5_emit_composite_primitive_solid;
2449
 
                else if (tmp->src.transform == NULL)
2450
 
                        tmp->prim_emit = gen5_emit_composite_primitive_identity_source;
2451
 
                else if (tmp->src.is_affine)
2452
 
                        tmp->prim_emit = gen5_emit_composite_primitive_affine_source;
2453
 
 
2454
 
                tmp->floats_per_vertex = 3 + !tmp->is_affine;
2455
2021
        }
2456
 
        tmp->floats_per_rect = 3*tmp->floats_per_vertex;
 
2022
        gen4_choose_composite_emitter(tmp);
2457
2023
 
2458
2024
        tmp->u.gen5.wm_kernel =
2459
2025
                gen5_choose_composite_kernel(tmp->op,
2460
2026
                                             tmp->mask.bo != NULL,
2461
2027
                                             tmp->has_component_alpha,
2462
2028
                                             tmp->is_affine);
2463
 
        tmp->u.gen5.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
 
2029
        tmp->u.gen5.ve_id = gen4_choose_composite_vertex_buffer(tmp);
2464
2030
 
2465
2031
        tmp->blt   = gen5_render_composite_blt;
2466
2032
        tmp->box   = gen5_render_composite_box;
2492
2058
}
2493
2059
 
2494
2060
#if !NO_COMPOSITE_SPANS
2495
 
inline static void
2496
 
gen5_emit_composite_texcoord(struct sna *sna,
2497
 
                             const struct sna_composite_channel *channel,
2498
 
                             int16_t x, int16_t y)
2499
 
{
2500
 
        float t[3];
2501
 
 
2502
 
        if (channel->is_affine) {
2503
 
                sna_get_transformed_coordinates(x + channel->offset[0],
2504
 
                                                y + channel->offset[1],
2505
 
                                                channel->transform,
2506
 
                                                &t[0], &t[1]);
2507
 
                OUT_VERTEX_F(t[0] * channel->scale[0]);
2508
 
                OUT_VERTEX_F(t[1] * channel->scale[1]);
2509
 
        } else {
2510
 
                t[0] = t[1] = 0; t[2] = 1;
2511
 
                sna_get_transformed_coordinates_3d(x + channel->offset[0],
2512
 
                                                   y + channel->offset[1],
2513
 
                                                   channel->transform,
2514
 
                                                   &t[0], &t[1], &t[2]);
2515
 
                OUT_VERTEX_F(t[0] * channel->scale[0]);
2516
 
                OUT_VERTEX_F(t[1] * channel->scale[1]);
2517
 
                OUT_VERTEX_F(t[2]);
2518
 
        }
2519
 
}
2520
 
 
2521
 
inline static void
2522
 
gen5_emit_composite_texcoord_affine(struct sna *sna,
2523
 
                                    const struct sna_composite_channel *channel,
2524
 
                                    int16_t x, int16_t y)
2525
 
{
2526
 
        float t[2];
2527
 
 
2528
 
        sna_get_transformed_coordinates(x + channel->offset[0],
2529
 
                                        y + channel->offset[1],
2530
 
                                        channel->transform,
2531
 
                                        &t[0], &t[1]);
2532
 
        OUT_VERTEX_F(t[0] * channel->scale[0]);
2533
 
        OUT_VERTEX_F(t[1] * channel->scale[1]);
2534
 
}
2535
 
 
2536
 
inline static void
2537
 
gen5_emit_composite_spans_vertex(struct sna *sna,
2538
 
                                 const struct sna_composite_spans_op *op,
2539
 
                                 int16_t x, int16_t y)
2540
 
{
2541
 
        OUT_VERTEX(x, y);
2542
 
        gen5_emit_composite_texcoord(sna, &op->base.src, x, y);
2543
 
}
2544
 
 
2545
 
fastcall static void
2546
 
gen5_emit_composite_spans_primitive(struct sna *sna,
2547
 
                                    const struct sna_composite_spans_op *op,
2548
 
                                    const BoxRec *box,
2549
 
                                    float opacity)
2550
 
{
2551
 
        gen5_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
2552
 
        OUT_VERTEX_F(opacity);
2553
 
        OUT_VERTEX_F(1);
2554
 
        if (!op->base.is_affine)
2555
 
                OUT_VERTEX_F(1);
2556
 
 
2557
 
        gen5_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
2558
 
        OUT_VERTEX_F(opacity);
2559
 
        OUT_VERTEX_F(1);
2560
 
        if (!op->base.is_affine)
2561
 
                OUT_VERTEX_F(1);
2562
 
 
2563
 
        gen5_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
2564
 
        OUT_VERTEX_F(opacity);
2565
 
        OUT_VERTEX_F(0);
2566
 
        if (!op->base.is_affine)
2567
 
                OUT_VERTEX_F(1);
2568
 
}
2569
 
 
2570
 
fastcall static void
2571
 
gen5_emit_composite_spans_solid(struct sna *sna,
2572
 
                                const struct sna_composite_spans_op *op,
2573
 
                                const BoxRec *box,
2574
 
                                float opacity)
2575
 
{
2576
 
        OUT_VERTEX(box->x2, box->y2);
2577
 
        OUT_VERTEX_F(1); OUT_VERTEX_F(1);
2578
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
2579
 
 
2580
 
        OUT_VERTEX(box->x1, box->y2);
2581
 
        OUT_VERTEX_F(0); OUT_VERTEX_F(1);
2582
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
2583
 
 
2584
 
        OUT_VERTEX(box->x1, box->y1);
2585
 
        OUT_VERTEX_F(0); OUT_VERTEX_F(0);
2586
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
2587
 
}
2588
 
 
2589
 
fastcall static void
2590
 
gen5_emit_composite_spans_affine(struct sna *sna,
2591
 
                                 const struct sna_composite_spans_op *op,
2592
 
                                 const BoxRec *box,
2593
 
                                 float opacity)
2594
 
{
2595
 
        OUT_VERTEX(box->x2, box->y2);
2596
 
        gen5_emit_composite_texcoord_affine(sna, &op->base.src,
2597
 
                                            box->x2, box->y2);
2598
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
2599
 
 
2600
 
        OUT_VERTEX(box->x1, box->y2);
2601
 
        gen5_emit_composite_texcoord_affine(sna, &op->base.src,
2602
 
                                            box->x1, box->y2);
2603
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
2604
 
 
2605
 
        OUT_VERTEX(box->x1, box->y1);
2606
 
        gen5_emit_composite_texcoord_affine(sna, &op->base.src,
2607
 
                                            box->x1, box->y1);
2608
 
        OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
2609
 
}
2610
 
 
2611
2061
fastcall static void
2612
2062
gen5_render_composite_spans_box(struct sna *sna,
2613
2063
                                const struct sna_composite_spans_op *op,
2660
2110
gen5_render_composite_spans_done(struct sna *sna,
2661
2111
                                 const struct sna_composite_spans_op *op)
2662
2112
{
2663
 
        if (sna->render_state.gen5.vertex_offset)
2664
 
                gen5_vertex_flush(sna);
 
2113
        if (sna->render.vertex_offset)
 
2114
                gen4_vertex_flush(sna);
2665
2115
 
2666
2116
        DBG(("%s()\n", __FUNCTION__));
2667
2117
 
2668
 
        kgem_bo_destroy(&sna->kgem, op->base.mask.bo);
2669
 
        if (op->base.src.bo)
2670
 
                kgem_bo_destroy(&sna->kgem, op->base.src.bo);
2671
 
 
 
2118
        kgem_bo_destroy(&sna->kgem, op->base.src.bo);
2672
2119
        sna_render_composite_redirect_done(sna, &op->base);
2673
2120
}
2674
2121
 
2696
2143
        }
2697
2144
 
2698
2145
        if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) {
2699
 
                if ((flags & COMPOSITE_SPANS_INPLACE_HINT) == 0) {
2700
 
                        struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
2701
 
                        assert(priv);
2702
 
 
2703
 
                        if ((priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) ||
2704
 
                            (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))) {
2705
 
                                return true;
2706
 
                        }
2707
 
                }
 
2146
                struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
 
2147
                assert(priv);
 
2148
 
 
2149
                if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
 
2150
                        return true;
 
2151
 
 
2152
                if ((flags & COMPOSITE_SPANS_INPLACE_HINT) == 0 &&
 
2153
                    priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))
 
2154
                        return true;
2708
2155
 
2709
2156
                DBG(("%s: fallback, non-rectilinear spans to idle bo\n",
2710
2157
                     __FUNCTION__));
2759
2206
                break;
2760
2207
        }
2761
2208
 
2762
 
        tmp->base.mask.bo = sna_render_get_solid(sna, 0);
2763
 
        if (tmp->base.mask.bo == NULL)
2764
 
                goto cleanup_src;
 
2209
        tmp->base.mask.bo = NULL;
2765
2210
 
2766
2211
        tmp->base.is_affine = tmp->base.src.is_affine;
2767
2212
        tmp->base.has_component_alpha = false;
2768
2213
        tmp->base.need_magic_ca_pass = false;
2769
2214
 
2770
 
        tmp->prim_emit = gen5_emit_composite_spans_primitive;
2771
 
        if (tmp->base.src.is_solid)
2772
 
                tmp->prim_emit = gen5_emit_composite_spans_solid;
2773
 
        else if (tmp->base.is_affine)
2774
 
                tmp->prim_emit = gen5_emit_composite_spans_affine;
2775
 
        tmp->base.floats_per_vertex = 5 + 2*!tmp->base.is_affine;
2776
 
        tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
 
2215
        gen4_choose_spans_emitter(tmp);
2777
2216
 
2778
2217
        tmp->base.u.gen5.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine;
2779
 
        tmp->base.u.gen5.ve_id = 1 << 1 | tmp->base.is_affine;
 
2218
        tmp->base.u.gen5.ve_id = gen4_choose_spans_vertex_buffer(&tmp->base);
2780
2219
 
2781
2220
        tmp->box   = gen5_render_composite_spans_box;
2782
2221
        tmp->boxes = gen5_render_composite_spans_boxes;
2907
2346
                        if (box[i].y2 > extents.y2)
2908
2347
                                extents.y2 = box[i].y2;
2909
2348
                }
2910
 
 
2911
2349
                if (!sna_render_composite_redirect(sna, &tmp,
2912
2350
                                                   extents.x1 + dst_dx,
2913
2351
                                                   extents.y1 + dst_dy,
2941
2379
                                               extents.x2 - extents.x1,
2942
2380
                                               extents.y2 - extents.y1))
2943
2381
                        goto fallback_tiled_dst;
 
2382
 
 
2383
                src_dx += tmp.src.offset[0];
 
2384
                src_dy += tmp.src.offset[1];
2944
2385
        } else {
2945
2386
                tmp.src.bo = kgem_bo_reference(src_bo);
2946
2387
                tmp.src.width  = src->drawable.width;
2947
2388
                tmp.src.height = src->drawable.height;
2948
 
                tmp.src.offset[0] = tmp.src.offset[1] = 0;
2949
 
                tmp.src.scale[0] = 1.f/src->drawable.width;
2950
 
                tmp.src.scale[1] = 1.f/src->drawable.height;
2951
2389
        }
2952
2390
 
2953
2391
        tmp.is_affine = true;
2954
 
        tmp.floats_per_vertex = 3;
2955
 
        tmp.floats_per_rect = 9;
 
2392
        tmp.floats_per_vertex = 2;
 
2393
        tmp.floats_per_rect = 6;
2956
2394
        tmp.u.gen5.wm_kernel = WM_KERNEL;
2957
 
        tmp.u.gen5.ve_id = 1;
 
2395
        tmp.u.gen5.ve_id = VERTEX_2s2s;
2958
2396
 
2959
2397
        if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
2960
2398
                kgem_submit(&sna->kgem);
2966
2404
        dst_dy += tmp.dst.y;
2967
2405
        tmp.dst.x = tmp.dst.y = 0;
2968
2406
 
2969
 
        src_dx += tmp.src.offset[0];
2970
 
        src_dy += tmp.src.offset[1];
2971
 
 
2972
2407
        gen5_copy_bind_surfaces(sna, &tmp);
2973
2408
        gen5_align_vertex(sna, &tmp);
2974
2409
 
2985
2420
                             box->x1 + dst_dx, box->y1 + dst_dy,
2986
2421
                             box->x2 - box->x1, box->y2 - box->y1));
2987
2422
                        OUT_VERTEX(box->x2 + dst_dx, box->y2 + dst_dy);
2988
 
                        OUT_VERTEX_F((box->x2 + src_dx) * tmp.src.scale[0]);
2989
 
                        OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]);
 
2423
                        OUT_VERTEX(box->x2 + src_dx, box->y2 + src_dy);
2990
2424
 
2991
2425
                        OUT_VERTEX(box->x1 + dst_dx, box->y2 + dst_dy);
2992
 
                        OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]);
2993
 
                        OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]);
 
2426
                        OUT_VERTEX(box->x1 + src_dx, box->y2 + src_dy);
2994
2427
 
2995
2428
                        OUT_VERTEX(box->x1 + dst_dx, box->y1 + dst_dy);
2996
 
                        OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]);
2997
 
                        OUT_VERTEX_F((box->y1 + src_dy) * tmp.src.scale[1]);
 
2429
                        OUT_VERTEX(box->x1 + src_dx, box->y1 + src_dy);
2998
2430
 
2999
2431
                        box++;
3000
2432
                } while (--n_this_time);
3001
2433
        } while (n);
3002
2434
 
3003
 
        gen5_vertex_flush(sna);
 
2435
        gen4_vertex_flush(sna);
3004
2436
        sna_render_composite_redirect_done(sna, &tmp);
3005
2437
        kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3006
2438
        return true;
3030
2462
        gen5_get_rectangles(sna, &op->base, 1, gen5_copy_bind_surfaces);
3031
2463
 
3032
2464
        OUT_VERTEX(dx+w, dy+h);
3033
 
        OUT_VERTEX_F((sx+w)*op->base.src.scale[0]);
3034
 
        OUT_VERTEX_F((sy+h)*op->base.src.scale[1]);
 
2465
        OUT_VERTEX(sx+w, sy+h);
3035
2466
 
3036
2467
        OUT_VERTEX(dx, dy+h);
3037
 
        OUT_VERTEX_F(sx*op->base.src.scale[0]);
3038
 
        OUT_VERTEX_F((sy+h)*op->base.src.scale[1]);
 
2468
        OUT_VERTEX(sx, sy+h);
3039
2469
 
3040
2470
        OUT_VERTEX(dx, dy);
3041
 
        OUT_VERTEX_F(sx*op->base.src.scale[0]);
3042
 
        OUT_VERTEX_F(sy*op->base.src.scale[1]);
 
2471
        OUT_VERTEX(sx, sy);
3043
2472
}
3044
2473
 
3045
2474
static void
3046
2475
gen5_render_copy_done(struct sna *sna,
3047
2476
                      const struct sna_copy_op *op)
3048
2477
{
3049
 
        if (sna->render_state.gen5.vertex_offset)
3050
 
                gen5_vertex_flush(sna);
 
2478
        if (sna->render.vertex_offset)
 
2479
                gen4_vertex_flush(sna);
3051
2480
 
3052
2481
        DBG(("%s()\n", __FUNCTION__));
3053
2482
}
3101
2530
                gen5_get_card_format(op->base.src.pict_format);
3102
2531
        op->base.src.width  = src->drawable.width;
3103
2532
        op->base.src.height = src->drawable.height;
3104
 
        op->base.src.scale[0] = 1.f/src->drawable.width;
3105
 
        op->base.src.scale[1] = 1.f/src->drawable.height;
3106
2533
        op->base.src.filter = SAMPLER_FILTER_NEAREST;
3107
2534
        op->base.src.repeat = SAMPLER_EXTEND_NONE;
3108
2535
 
3109
2536
        op->base.is_affine = true;
3110
 
        op->base.floats_per_vertex = 3;
3111
 
        op->base.floats_per_rect = 9;
 
2537
        op->base.floats_per_vertex = 2;
 
2538
        op->base.floats_per_rect = 6;
3112
2539
        op->base.u.gen5.wm_kernel = WM_KERNEL;
3113
 
        op->base.u.gen5.ve_id = 1;
 
2540
        op->base.u.gen5.ve_id = VERTEX_2s2s;
3114
2541
 
3115
 
        if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))  {
 
2542
        if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
3116
2543
                kgem_submit(&sna->kgem);
3117
2544
                if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
3118
2545
                        goto fallback;
3229
2656
                                                     dst, dst_bo, box, n);
3230
2657
        }
3231
2658
 
3232
 
        if (op == PictOpClear)
 
2659
        if (op == PictOpClear) {
3233
2660
                pixel = 0;
3234
 
        else if (!sna_get_pixel_from_rgba(&pixel,
3235
 
                                          color->red,
3236
 
                                          color->green,
3237
 
                                          color->blue,
3238
 
                                          color->alpha,
3239
 
                                          PICT_a8r8g8b8))
 
2661
                op = PictOpSrc;
 
2662
        } else if (!sna_get_pixel_from_rgba(&pixel,
 
2663
                                            color->red,
 
2664
                                            color->green,
 
2665
                                            color->blue,
 
2666
                                            color->alpha,
 
2667
                                            PICT_a8r8g8b8))
3240
2668
                return false;
3241
2669
 
 
2670
        DBG(("%s(%08x x %d)\n", __FUNCTION__, pixel, n));
 
2671
 
3242
2672
        memset(&tmp, 0, sizeof(tmp));
3243
2673
 
3244
2674
        tmp.op = op;
3254
2684
        tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
3255
2685
 
3256
2686
        tmp.is_affine = true;
3257
 
        tmp.floats_per_vertex = 3;
3258
 
        tmp.floats_per_rect = 9;
 
2687
        tmp.floats_per_vertex = 2;
 
2688
        tmp.floats_per_rect = 6;
3259
2689
        tmp.u.gen5.wm_kernel = WM_KERNEL;
3260
 
        tmp.u.gen5.ve_id = 1;
 
2690
        tmp.u.gen5.ve_id = VERTEX_2s2s;
3261
2691
 
3262
2692
        if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
3263
2693
                kgem_submit(&sna->kgem);
3278
2708
                        DBG(("  (%d, %d), (%d, %d)\n",
3279
2709
                             box->x1, box->y1, box->x2, box->y2));
3280
2710
                        OUT_VERTEX(box->x2, box->y2);
3281
 
                        OUT_VERTEX_F(1);
3282
 
                        OUT_VERTEX_F(1);
 
2711
                        OUT_VERTEX(1, 1);
3283
2712
 
3284
2713
                        OUT_VERTEX(box->x1, box->y2);
3285
 
                        OUT_VERTEX_F(0);
3286
 
                        OUT_VERTEX_F(1);
 
2714
                        OUT_VERTEX(0, 1);
3287
2715
 
3288
2716
                        OUT_VERTEX(box->x1, box->y1);
3289
 
                        OUT_VERTEX_F(0);
3290
 
                        OUT_VERTEX_F(0);
 
2717
                        OUT_VERTEX(0, 0);
3291
2718
 
3292
2719
                        box++;
3293
2720
                } while (--n_this_time);
3294
2721
        } while (n);
3295
2722
 
3296
 
        gen5_vertex_flush(sna);
 
2723
        gen4_vertex_flush(sna);
3297
2724
        kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3298
2725
        return true;
3299
2726
}
3308
2735
        gen5_get_rectangles(sna, &op->base, 1, gen5_fill_bind_surfaces);
3309
2736
 
3310
2737
        OUT_VERTEX(x+w, y+h);
3311
 
        OUT_VERTEX_F(1);
3312
 
        OUT_VERTEX_F(1);
 
2738
        OUT_VERTEX(1, 1);
3313
2739
 
3314
2740
        OUT_VERTEX(x, y+h);
3315
 
        OUT_VERTEX_F(0);
3316
 
        OUT_VERTEX_F(1);
 
2741
        OUT_VERTEX(0, 1);
3317
2742
 
3318
2743
        OUT_VERTEX(x, y);
3319
 
        OUT_VERTEX_F(0);
3320
 
        OUT_VERTEX_F(0);
 
2744
        OUT_VERTEX(0, 0);
3321
2745
}
3322
2746
 
3323
2747
fastcall static void
3331
2755
        gen5_get_rectangles(sna, &op->base, 1, gen5_fill_bind_surfaces);
3332
2756
 
3333
2757
        OUT_VERTEX(box->x2, box->y2);
3334
 
        OUT_VERTEX_F(1);
3335
 
        OUT_VERTEX_F(1);
 
2758
        OUT_VERTEX(1, 1);
3336
2759
 
3337
2760
        OUT_VERTEX(box->x1, box->y2);
3338
 
        OUT_VERTEX_F(0);
3339
 
        OUT_VERTEX_F(1);
 
2761
        OUT_VERTEX(0, 1);
3340
2762
 
3341
2763
        OUT_VERTEX(box->x1, box->y1);
3342
 
        OUT_VERTEX_F(0);
3343
 
        OUT_VERTEX_F(0);
 
2764
        OUT_VERTEX(0, 0);
3344
2765
}
3345
2766
 
3346
2767
fastcall static void
3361
2782
 
3362
2783
                do {
3363
2784
                        OUT_VERTEX(box->x2, box->y2);
3364
 
                        OUT_VERTEX_F(1);
3365
 
                        OUT_VERTEX_F(1);
 
2785
                        OUT_VERTEX(1, 1);
3366
2786
 
3367
2787
                        OUT_VERTEX(box->x1, box->y2);
3368
 
                        OUT_VERTEX_F(0);
3369
 
                        OUT_VERTEX_F(1);
 
2788
                        OUT_VERTEX(0, 1);
3370
2789
 
3371
2790
                        OUT_VERTEX(box->x1, box->y1);
3372
 
                        OUT_VERTEX_F(0);
3373
 
                        OUT_VERTEX_F(0);
 
2791
                        OUT_VERTEX(0, 0);
3374
2792
                        box++;
3375
2793
                } while (--nbox_this_time);
3376
2794
        } while (nbox);
3380
2798
gen5_render_fill_op_done(struct sna *sna,
3381
2799
                         const struct sna_fill_op *op)
3382
2800
{
3383
 
        if (sna->render_state.gen5.vertex_offset)
3384
 
                gen5_vertex_flush(sna);
 
2801
        if (sna->render.vertex_offset)
 
2802
                gen4_vertex_flush(sna);
3385
2803
        kgem_bo_destroy(&sna->kgem, op->base.src.bo);
3386
2804
 
3387
2805
        DBG(("%s()\n", __FUNCTION__));
3436
2854
        op->base.mask.repeat = SAMPLER_EXTEND_NONE;
3437
2855
 
3438
2856
        op->base.is_affine = true;
3439
 
        op->base.floats_per_vertex = 3;
3440
 
        op->base.floats_per_rect = 9;
 
2857
        op->base.floats_per_vertex = 2;
 
2858
        op->base.floats_per_rect = 6;
3441
2859
        op->base.u.gen5.wm_kernel = WM_KERNEL;
3442
 
        op->base.u.gen5.ve_id = 1;
 
2860
        op->base.u.gen5.ve_id = VERTEX_2s2s;
3443
2861
 
3444
2862
        if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
3445
2863
                kgem_submit(&sna->kgem);
3524
2942
        tmp.mask.repeat = SAMPLER_EXTEND_NONE;
3525
2943
 
3526
2944
        tmp.is_affine = true;
3527
 
        tmp.floats_per_vertex = 3;
3528
 
        tmp.floats_per_rect = 9;
 
2945
        tmp.floats_per_vertex = 2;
 
2946
        tmp.floats_per_rect = 6;
3529
2947
        tmp.has_component_alpha = 0;
3530
2948
        tmp.need_magic_ca_pass = false;
3531
2949
 
3532
2950
        tmp.u.gen5.wm_kernel = WM_KERNEL;
3533
 
        tmp.u.gen5.ve_id = 1;
 
2951
        tmp.u.gen5.ve_id = VERTEX_2s2s;
3534
2952
 
3535
2953
        if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
3536
2954
                _kgem_submit(&sna->kgem);
3544
2962
 
3545
2963
        DBG(("  (%d, %d), (%d, %d)\n", x1, y1, x2, y2));
3546
2964
        OUT_VERTEX(x2, y2);
3547
 
        OUT_VERTEX_F(1);
3548
 
        OUT_VERTEX_F(1);
 
2965
        OUT_VERTEX(1, 1);
3549
2966
 
3550
2967
        OUT_VERTEX(x1, y2);
3551
 
        OUT_VERTEX_F(0);
3552
 
        OUT_VERTEX_F(1);
 
2968
        OUT_VERTEX(0, 1);
3553
2969
 
3554
2970
        OUT_VERTEX(x1, y1);
3555
 
        OUT_VERTEX_F(0);
3556
 
        OUT_VERTEX_F(0);
 
2971
        OUT_VERTEX(0, 0);
3557
2972
 
3558
 
        gen5_vertex_flush(sna);
 
2973
        gen4_vertex_flush(sna);
3559
2974
        kgem_bo_destroy(&sna->kgem, tmp.src.bo);
3560
2975
 
3561
2976
        return true;
3564
2979
static void
3565
2980
gen5_render_flush(struct sna *sna)
3566
2981
{
3567
 
        gen5_vertex_close(sna);
 
2982
        gen4_vertex_close(sna);
 
2983
 
 
2984
        assert(sna->render.vb_id == 0);
 
2985
        assert(sna->render.vertex_offset == 0);
3568
2986
}
3569
2987
 
3570
2988
static void
3571
2989
gen5_render_context_switch(struct kgem *kgem,
3572
2990
                           int new_mode)
3573
2991
{
3574
 
        if (!kgem->mode)
 
2992
        if (!kgem->nbatch)
3575
2993
                return;
3576
2994
 
3577
2995
        /* WaNonPipelinedStateCommandFlush
3635
3053
static void gen5_render_reset(struct sna *sna)
3636
3054
{
3637
3055
        sna->render_state.gen5.needs_invariant = true;
3638
 
        sna->render_state.gen5.vb_id = 0;
3639
3056
        sna->render_state.gen5.ve_id = -1;
3640
3057
        sna->render_state.gen5.last_primitive = -1;
3641
 
        sna->render_state.gen5.last_pipelined_pointers = 0;
 
3058
        sna->render_state.gen5.last_pipelined_pointers = -1;
3642
3059
 
3643
3060
        sna->render_state.gen5.drawrect_offset = -1;
3644
3061
        sna->render_state.gen5.drawrect_limit = -1;
3764
3181
        state->thread1.binding_table_entry_count = 0;
3765
3182
}
3766
3183
 
3767
 
static uint32_t gen5_create_cc_viewport(struct sna_static_stream *stream)
3768
 
{
3769
 
        struct gen5_cc_viewport vp;
3770
 
 
3771
 
        vp.min_depth = -1.e35;
3772
 
        vp.max_depth = 1.e35;
3773
 
 
3774
 
        return sna_static_stream_add(stream, &vp, sizeof(vp), 32);
3775
 
}
3776
 
 
3777
3184
static uint32_t gen5_create_cc_unit_state(struct sna_static_stream *stream)
3778
3185
{
3779
3186
        uint8_t *ptr, *base;
3780
 
        uint32_t vp;
3781
3187
        int i, j;
3782
3188
 
3783
 
        vp = gen5_create_cc_viewport(stream);
3784
3189
        base = ptr =
3785
3190
                sna_static_stream_map(stream,
3786
3191
                                      GEN5_BLENDFACTOR_COUNT*GEN5_BLENDFACTOR_COUNT*64,
3793
3198
 
3794
3199
                        state->cc3.blend_enable =
3795
3200
                                !(j == GEN5_BLENDFACTOR_ZERO && i == GEN5_BLENDFACTOR_ONE);
3796
 
                        state->cc4.cc_viewport_state_offset = vp >> 5;
3797
3201
 
3798
3202
                        state->cc5.logicop_func = 0xc;  /* COPY */
3799
3203
                        state->cc5.ia_blend_function = GEN5_BLENDFUNCTION_ADD;
3877
3281
                                        for (m = 0; m < KERNEL_COUNT; m++) {
3878
3282
                                                gen5_init_wm_state(&wm_state->state,
3879
3283
                                                                   wm_kernels[m].has_mask,
3880
 
                                                                   wm[m],
3881
 
                                                                   sampler_state);
 
3284
                                                                   wm[m], sampler_state);
3882
3285
                                                wm_state++;
3883
3286
                                        }
3884
3287
                                }
3901
3304
        sna->kgem.retire = gen5_render_retire;
3902
3305
        sna->kgem.expire = gen5_render_expire;
3903
3306
 
 
3307
#if !NO_COMPOSITE
3904
3308
        sna->render.composite = gen5_render_composite;
 
3309
#endif
3905
3310
#if !NO_COMPOSITE_SPANS
3906
3311
        sna->render.check_composite_spans = gen5_check_composite_spans;
3907
3312
        sna->render.composite_spans = gen5_render_composite_spans;