Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3
 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4
 develop this 3D driver.
5
 
6
 Permission is hereby granted, free of charge, to any person obtaining
7
 a copy of this software and associated documentation files (the
8
 "Software"), to deal in the Software without restriction, including
9
 without limitation the rights to use, copy, modify, merge, publish,
10
 distribute, sublicense, and/or sell copies of the Software, and to
11
 permit persons to whom the Software is furnished to do so, subject to
12
 the following conditions:
13
 
14
 The above copyright notice and this permission notice (including the
15
 next paragraph) shall be included in all copies or substantial
16
 portions of the Software.
17
 
18
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
26
 **********************************************************************/
27
 /*
28
  * Authors:
29
  *   Keith Whitwell 
30
  */
31
 
32
#include "main/glheader.h"
33
#include "main/macros.h"
34
#include "main/enums.h"
35
#include "main/transformfeedback.h"
36
 
37
#include "intel_batchbuffer.h"
38
 
39
#include "brw_defines.h"
40
#include "brw_context.h"
41
#include "brw_eu.h"
42
#include "brw_util.h"
43
#include "brw_state.h"
44
#include "brw_gs.h"
45
 
46
#include "glsl/ralloc.h"
47
 
48
static void compile_gs_prog( struct brw_context *brw,
49
			     struct brw_gs_prog_key *key )
50
{
51
   struct brw_gs_compile c;
52
   const GLuint *program;
53
   void *mem_ctx;
54
   GLuint program_size;
55
 
56
   memset(&c, 0, sizeof(c));
57
 
58
   c.key = *key;
59
   c.vue_map = brw->vs.prog_data->base.vue_map;
60
   c.nr_regs = (c.vue_map.num_slots + 1)/2;
61
 
62
   mem_ctx = ralloc_context(NULL);
63
 
64
   /* Begin the compilation:
65
    */
66
   brw_init_compile(brw, &c.func, mem_ctx);
67
 
68
   c.func.single_program_flow = 1;
69
 
70
   /* For some reason the thread is spawned with only 4 channels
71
    * unmasked.
72
    */
73
   brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
74
 
75
   if (brw->gen >= 6) {
76
      unsigned num_verts;
77
      bool check_edge_flag;
78
      /* On Sandybridge, we use the GS for implementing transform feedback
79
       * (called "Stream Out" in the PRM).
80
       */
81
      switch (key->primitive) {
82
      case _3DPRIM_POINTLIST:
83
         num_verts = 1;
84
         check_edge_flag = false;
85
	 break;
86
      case _3DPRIM_LINELIST:
87
      case _3DPRIM_LINESTRIP:
88
      case _3DPRIM_LINELOOP:
89
         num_verts = 2;
90
         check_edge_flag = false;
91
	 break;
92
      case _3DPRIM_TRILIST:
93
      case _3DPRIM_TRIFAN:
94
      case _3DPRIM_TRISTRIP:
95
      case _3DPRIM_RECTLIST:
96
	 num_verts = 3;
97
         check_edge_flag = false;
98
         break;
99
      case _3DPRIM_QUADLIST:
100
      case _3DPRIM_QUADSTRIP:
101
      case _3DPRIM_POLYGON:
102
         num_verts = 3;
103
         check_edge_flag = true;
104
         break;
105
      default:
106
	 assert(!"Unexpected primitive type in Gen6 SOL program.");
107
	 return;
108
      }
109
      gen6_sol_program(&c, key, num_verts, check_edge_flag);
110
   } else {
111
      /* On Gen4-5, we use the GS to decompose certain types of primitives.
112
       * Note that primitives which don't require a GS program have already
113
       * been weeded out by now.
114
       */
115
      switch (key->primitive) {
116
      case _3DPRIM_QUADLIST:
117
	 brw_gs_quads( &c, key );
118
	 break;
119
      case _3DPRIM_QUADSTRIP:
120
	 brw_gs_quad_strip( &c, key );
121
	 break;
122
      case _3DPRIM_LINELOOP:
123
	 brw_gs_lines( &c );
124
	 break;
125
      default:
126
	 ralloc_free(mem_ctx);
127
	 return;
128
      }
129
   }
130
 
131
   /* get the program
132
    */
133
   program = brw_get_program(&c.func, &program_size);
134
 
135
   if (unlikely(INTEL_DEBUG & DEBUG_GS)) {
136
      int i;
137
 
138
      printf("gs:\n");
139
      for (i = 0; i < program_size / sizeof(struct brw_instruction); i++)
140
	 brw_disasm(stdout, &((struct brw_instruction *)program)[i],
141
		    brw->gen);
142
      printf("\n");
143
    }
144
 
145
   brw_upload_cache(&brw->cache, BRW_GS_PROG,
146
		    &c.key, sizeof(c.key),
147
		    program, program_size,
148
		    &c.prog_data, sizeof(c.prog_data),
149
		    &brw->gs.prog_offset, &brw->gs.prog_data);
150
   ralloc_free(mem_ctx);
151
}
152
 
153
static void populate_key( struct brw_context *brw,
154
			  struct brw_gs_prog_key *key )
155
{
156
   static const unsigned swizzle_for_offset[4] = {
157
      BRW_SWIZZLE4(0, 1, 2, 3),
158
      BRW_SWIZZLE4(1, 2, 3, 3),
159
      BRW_SWIZZLE4(2, 3, 3, 3),
160
      BRW_SWIZZLE4(3, 3, 3, 3)
161
   };
162
 
163
   struct gl_context *ctx = &brw->ctx;
164
 
165
   memset(key, 0, sizeof(*key));
166
 
167
   /* CACHE_NEW_VS_PROG (part of VUE map) */
168
   key->attrs = brw->vs.prog_data->base.vue_map.slots_valid;
169
 
170
   /* BRW_NEW_PRIMITIVE */
171
   key->primitive = brw->primitive;
172
 
173
   /* _NEW_LIGHT */
174
   key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
175
   if (key->primitive == _3DPRIM_QUADLIST && ctx->Light.ShadeModel != GL_FLAT) {
176
      /* Provide consistent primitive order with brw_set_prim's
177
       * optimization of single quads to trifans.
178
       */
179
      key->pv_first = true;
180
   }
181
 
182
   if (brw->gen >= 7) {
183
      /* On Gen7 and later, we don't use GS (yet). */
184
      key->need_gs_prog = false;
185
   } else if (brw->gen == 6) {
186
      /* On Gen6, GS is used for transform feedback. */
187
      /* BRW_NEW_TRANSFORM_FEEDBACK */
188
      if (_mesa_is_xfb_active_and_unpaused(ctx)) {
189
         const struct gl_shader_program *shaderprog =
190
            ctx->Shader.CurrentVertexProgram;
191
         const struct gl_transform_feedback_info *linked_xfb_info =
192
            &shaderprog->LinkedTransformFeedback;
193
         int i;
194
 
195
         /* Make sure that the VUE slots won't overflow the unsigned chars in
196
          * key->transform_feedback_bindings[].
197
          */
198
         STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256);
199
 
200
         /* Make sure that we don't need more binding table entries than we've
201
          * set aside for use in transform feedback.  (We shouldn't, since we
202
          * set aside enough binding table entries to have one per component).
203
          */
204
         assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
205
 
206
         key->need_gs_prog = true;
207
         key->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
208
         for (i = 0; i < key->num_transform_feedback_bindings; ++i) {
209
            key->transform_feedback_bindings[i] =
210
               linked_xfb_info->Outputs[i].OutputRegister;
211
            key->transform_feedback_swizzles[i] =
212
               swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
213
         }
214
      }
215
   } else {
216
      /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP
217
       * into simpler primitives.
218
       */
219
      key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST ||
220
                           brw->primitive == _3DPRIM_QUADSTRIP ||
221
                           brw->primitive == _3DPRIM_LINELOOP);
222
   }
223
}
224
 
225
/* Calculate interpolants for triangle and line rasterization.
226
 */
227
static void
228
brw_upload_gs_prog(struct brw_context *brw)
229
{
230
   struct brw_gs_prog_key key;
231
   /* Populate the key:
232
    */
233
   populate_key(brw, &key);
234
 
235
   if (brw->gs.prog_active != key.need_gs_prog) {
236
      brw->state.dirty.cache |= CACHE_NEW_GS_PROG;
237
      brw->gs.prog_active = key.need_gs_prog;
238
   }
239
 
240
   if (brw->gs.prog_active) {
241
      if (!brw_search_cache(&brw->cache, BRW_GS_PROG,
242
			    &key, sizeof(key),
243
			    &brw->gs.prog_offset, &brw->gs.prog_data)) {
244
	 compile_gs_prog( brw, &key );
245
      }
246
   }
247
}
248
 
249
 
250
const struct brw_tracked_state brw_gs_prog = {
251
   .dirty = {
252
      .mesa  = (_NEW_LIGHT),
253
      .brw   = (BRW_NEW_PRIMITIVE |
254
                BRW_NEW_TRANSFORM_FEEDBACK),
255
      .cache = CACHE_NEW_VS_PROG
256
   },
257
   .emit = brw_upload_gs_prog
258
};