Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4358 Rev 4401
1
/*
1
/*
2
 * Copyright © 2011 Intel Corporation
2
 * Copyright © 2011 Intel Corporation
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice (including the next
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
13
 * Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
 * IN THE SOFTWARE.
21
 * IN THE SOFTWARE.
22
 */
22
 */
23
 
23
 
24
/** \file gen6_sol.c
24
/** \file gen6_sol.c
25
 *
25
 *
26
 * Code to initialize the binding table entries used by transform feedback.
26
 * Code to initialize the binding table entries used by transform feedback.
27
 */
27
 */
28
 
28
 
29
#include "main/macros.h"
29
#include "main/macros.h"
30
#include "brw_context.h"
30
#include "brw_context.h"
31
#include "intel_batchbuffer.h"
31
#include "intel_batchbuffer.h"
32
#include "brw_defines.h"
32
#include "brw_defines.h"
33
#include "brw_state.h"
33
#include "brw_state.h"
34
#include "main/transformfeedback.h"
34
#include "main/transformfeedback.h"
35
 
35
 
36
static void
36
static void
37
gen6_update_sol_surfaces(struct brw_context *brw)
37
gen6_update_sol_surfaces(struct brw_context *brw)
38
{
38
{
39
   struct gl_context *ctx = &brw->ctx;
39
   struct gl_context *ctx = &brw->ctx;
40
   /* BRW_NEW_TRANSFORM_FEEDBACK */
40
   /* BRW_NEW_TRANSFORM_FEEDBACK */
41
   struct gl_transform_feedback_object *xfb_obj =
41
   struct gl_transform_feedback_object *xfb_obj =
42
      ctx->TransformFeedback.CurrentObject;
42
      ctx->TransformFeedback.CurrentObject;
43
   /* BRW_NEW_VERTEX_PROGRAM */
43
   /* BRW_NEW_VERTEX_PROGRAM */
44
   const struct gl_shader_program *shaderprog =
44
   const struct gl_shader_program *shaderprog =
45
      ctx->Shader.CurrentVertexProgram;
45
      ctx->Shader.CurrentVertexProgram;
46
   const struct gl_transform_feedback_info *linked_xfb_info =
46
   const struct gl_transform_feedback_info *linked_xfb_info =
47
      &shaderprog->LinkedTransformFeedback;
47
      &shaderprog->LinkedTransformFeedback;
48
   int i;
48
   int i;
49
 
49
 
50
   for (i = 0; i < BRW_MAX_SOL_BINDINGS; ++i) {
50
   for (i = 0; i < BRW_MAX_SOL_BINDINGS; ++i) {
51
      const int surf_index = SURF_INDEX_SOL_BINDING(i);
51
      const int surf_index = SURF_INDEX_SOL_BINDING(i);
52
      if (_mesa_is_xfb_active_and_unpaused(ctx) &&
52
      if (_mesa_is_xfb_active_and_unpaused(ctx) &&
53
          i < linked_xfb_info->NumOutputs) {
53
          i < linked_xfb_info->NumOutputs) {
54
         unsigned buffer = linked_xfb_info->Outputs[i].OutputBuffer;
54
         unsigned buffer = linked_xfb_info->Outputs[i].OutputBuffer;
55
         unsigned buffer_offset =
55
         unsigned buffer_offset =
56
            xfb_obj->Offset[buffer] / 4 +
56
            xfb_obj->Offset[buffer] / 4 +
57
            linked_xfb_info->Outputs[i].DstOffset;
57
            linked_xfb_info->Outputs[i].DstOffset;
58
         brw_update_sol_surface(
58
         brw_update_sol_surface(
59
            brw, xfb_obj->Buffers[buffer], &brw->gs.surf_offset[surf_index],
59
            brw, xfb_obj->Buffers[buffer], &brw->gs.surf_offset[surf_index],
60
            linked_xfb_info->Outputs[i].NumComponents,
60
            linked_xfb_info->Outputs[i].NumComponents,
61
            linked_xfb_info->BufferStride[buffer], buffer_offset);
61
            linked_xfb_info->BufferStride[buffer], buffer_offset);
62
      } else {
62
      } else {
63
         brw->gs.surf_offset[surf_index] = 0;
63
         brw->gs.surf_offset[surf_index] = 0;
64
      }
64
      }
65
   }
65
   }
66
 
66
 
67
   brw->state.dirty.brw |= BRW_NEW_SURFACES;
67
   brw->state.dirty.brw |= BRW_NEW_SURFACES;
68
}
68
}
69
 
69
 
70
const struct brw_tracked_state gen6_sol_surface = {
70
const struct brw_tracked_state gen6_sol_surface = {
71
   .dirty = {
71
   .dirty = {
72
      .mesa = 0,
72
      .mesa = 0,
73
      .brw = (BRW_NEW_BATCH |
73
      .brw = (BRW_NEW_BATCH |
74
              BRW_NEW_VERTEX_PROGRAM |
74
              BRW_NEW_VERTEX_PROGRAM |
75
              BRW_NEW_TRANSFORM_FEEDBACK),
75
              BRW_NEW_TRANSFORM_FEEDBACK),
76
      .cache = 0
76
      .cache = 0
77
   },
77
   },
78
   .emit = gen6_update_sol_surfaces,
78
   .emit = gen6_update_sol_surfaces,
79
};
79
};
80
 
80
 
81
/**
81
/**
82
 * Constructs the binding table for the WM surface state, which maps unit
82
 * Constructs the binding table for the WM surface state, which maps unit
83
 * numbers to surface state objects.
83
 * numbers to surface state objects.
84
 */
84
 */
85
static void
85
static void
86
brw_gs_upload_binding_table(struct brw_context *brw)
86
brw_gs_upload_binding_table(struct brw_context *brw)
87
{
87
{
88
   struct gl_context *ctx = &brw->ctx;
88
   struct gl_context *ctx = &brw->ctx;
89
   /* BRW_NEW_VERTEX_PROGRAM */
89
   /* BRW_NEW_VERTEX_PROGRAM */
90
   const struct gl_shader_program *shaderprog =
90
   const struct gl_shader_program *shaderprog =
91
      ctx->Shader.CurrentVertexProgram;
91
      ctx->Shader.CurrentVertexProgram;
92
   bool has_surfaces = false;
92
   bool has_surfaces = false;
93
   uint32_t *bind;
93
   uint32_t *bind;
94
 
94
 
95
   if (shaderprog) {
95
   if (shaderprog) {
96
      const struct gl_transform_feedback_info *linked_xfb_info =
96
      const struct gl_transform_feedback_info *linked_xfb_info =
97
	 &shaderprog->LinkedTransformFeedback;
97
	 &shaderprog->LinkedTransformFeedback;
98
      /* Currently we only ever upload surfaces for SOL. */
98
      /* Currently we only ever upload surfaces for SOL. */
99
      has_surfaces = linked_xfb_info->NumOutputs != 0;
99
      has_surfaces = linked_xfb_info->NumOutputs != 0;
100
   }
100
   }
101
 
101
 
102
   /* Skip making a binding table if we don't have anything to put in it. */
102
   /* Skip making a binding table if we don't have anything to put in it. */
103
   if (!has_surfaces) {
103
   if (!has_surfaces) {
104
      if (brw->gs.bind_bo_offset != 0) {
104
      if (brw->gs.bind_bo_offset != 0) {
105
	 brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE;
105
	 brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE;
106
	 brw->gs.bind_bo_offset = 0;
106
	 brw->gs.bind_bo_offset = 0;
107
      }
107
      }
108
      return;
108
      return;
109
   }
109
   }
110
 
110
 
111
   /* Might want to calculate nr_surfaces first, to avoid taking up so much
111
   /* Might want to calculate nr_surfaces first, to avoid taking up so much
112
    * space for the binding table.
112
    * space for the binding table.
113
    */
113
    */
114
   bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
114
   bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
115
			  sizeof(uint32_t) * BRW_MAX_GS_SURFACES,
115
			  sizeof(uint32_t) * BRW_MAX_GS_SURFACES,
116
			  32, &brw->gs.bind_bo_offset);
116
			  32, &brw->gs.bind_bo_offset);
117
 
117
 
118
   /* BRW_NEW_SURFACES */
118
   /* BRW_NEW_SURFACES */
119
   memcpy(bind, brw->gs.surf_offset, BRW_MAX_GS_SURFACES * sizeof(uint32_t));
119
   memcpy(bind, brw->gs.surf_offset, BRW_MAX_GS_SURFACES * sizeof(uint32_t));
120
 
120
 
121
   brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE;
121
   brw->state.dirty.brw |= BRW_NEW_GS_BINDING_TABLE;
122
}
122
}
123
 
123
 
124
const struct brw_tracked_state gen6_gs_binding_table = {
124
const struct brw_tracked_state gen6_gs_binding_table = {
125
   .dirty = {
125
   .dirty = {
126
      .mesa = 0,
126
      .mesa = 0,
127
      .brw = (BRW_NEW_BATCH |
127
      .brw = (BRW_NEW_BATCH |
128
	      BRW_NEW_VERTEX_PROGRAM |
128
	      BRW_NEW_VERTEX_PROGRAM |
129
	      BRW_NEW_SURFACES),
129
	      BRW_NEW_SURFACES),
130
      .cache = 0
130
      .cache = 0
131
   },
131
   },
132
   .emit = brw_gs_upload_binding_table,
132
   .emit = brw_gs_upload_binding_table,
133
};
133
};
134
 
134
 
135
void
135
void
136
brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
136
brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
137
			     struct gl_transform_feedback_object *obj)
137
			     struct gl_transform_feedback_object *obj)
138
{
138
{
139
   struct brw_context *brw = brw_context(ctx);
139
   struct brw_context *brw = brw_context(ctx);
140
   const struct gl_shader_program *vs_prog =
140
   const struct gl_shader_program *vs_prog =
141
      ctx->Shader.CurrentVertexProgram;
141
      ctx->Shader.CurrentVertexProgram;
142
   const struct gl_transform_feedback_info *linked_xfb_info =
142
   const struct gl_transform_feedback_info *linked_xfb_info =
143
      &vs_prog->LinkedTransformFeedback;
143
      &vs_prog->LinkedTransformFeedback;
144
   struct gl_transform_feedback_object *xfb_obj =
144
   struct gl_transform_feedback_object *xfb_obj =
145
      ctx->TransformFeedback.CurrentObject;
145
      ctx->TransformFeedback.CurrentObject;
146
 
146
 
147
   assert(brw->gen == 6);
147
   assert(brw->gen == 6);
148
 
148
 
149
   /* Compute the maximum number of vertices that we can write without
149
   /* Compute the maximum number of vertices that we can write without
150
    * overflowing any of the buffers currently being used for feedback.
150
    * overflowing any of the buffers currently being used for feedback.
151
    */
151
    */
152
   unsigned max_index
152
   unsigned max_index
153
      = _mesa_compute_max_transform_feedback_vertices(xfb_obj,
153
      = _mesa_compute_max_transform_feedback_vertices(xfb_obj,
154
                                                      linked_xfb_info);
154
                                                      linked_xfb_info);
-
 
155
 
-
 
156
   /* 3DSTATE_GS_SVB_INDEX is non-pipelined. */
-
 
157
   intel_emit_post_sync_nonzero_flush(brw);
155
 
158
 
156
   /* Initialize the SVBI 0 register to zero and set the maximum index. */
159
   /* Initialize the SVBI 0 register to zero and set the maximum index. */
157
   BEGIN_BATCH(4);
160
   BEGIN_BATCH(4);
158
   OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
161
   OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
159
   OUT_BATCH(0); /* SVBI 0 */
162
   OUT_BATCH(0); /* SVBI 0 */
160
   OUT_BATCH(0); /* starting index */
163
   OUT_BATCH(0); /* starting index */
161
   OUT_BATCH(max_index);
164
   OUT_BATCH(max_index);
162
   ADVANCE_BATCH();
165
   ADVANCE_BATCH();
163
 
166
 
164
   /* Initialize the rest of the unused streams to sane values.  Otherwise,
167
   /* Initialize the rest of the unused streams to sane values.  Otherwise,
165
    * they may indicate that there is no room to write data and prevent
168
    * they may indicate that there is no room to write data and prevent
166
    * anything from happening at all.
169
    * anything from happening at all.
167
    */
170
    */
168
   for (int i = 1; i < 4; i++) {
171
   for (int i = 1; i < 4; i++) {
169
      BEGIN_BATCH(4);
172
      BEGIN_BATCH(4);
170
      OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
173
      OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
171
      OUT_BATCH(i << SVB_INDEX_SHIFT);
174
      OUT_BATCH(i << SVB_INDEX_SHIFT);
172
      OUT_BATCH(0); /* starting index */
175
      OUT_BATCH(0); /* starting index */
173
      OUT_BATCH(0xffffffff);
176
      OUT_BATCH(0xffffffff);
174
      ADVANCE_BATCH();
177
      ADVANCE_BATCH();
175
   }
178
   }
176
}
179
}
177
 
180
 
178
void
181
void
179
brw_end_transform_feedback(struct gl_context *ctx,
182
brw_end_transform_feedback(struct gl_context *ctx,
180
                           struct gl_transform_feedback_object *obj)
183
                           struct gl_transform_feedback_object *obj)
181
{
184
{
182
   /* After EndTransformFeedback, it's likely that the client program will try
185
   /* After EndTransformFeedback, it's likely that the client program will try
183
    * to draw using the contents of the transform feedback buffer as vertex
186
    * to draw using the contents of the transform feedback buffer as vertex
184
    * input.  In order for this to work, we need to flush the data through at
187
    * input.  In order for this to work, we need to flush the data through at
185
    * least the GS stage of the pipeline, and flush out the render cache.  For
188
    * least the GS stage of the pipeline, and flush out the render cache.  For
186
    * simplicity, just do a full flush.
189
    * simplicity, just do a full flush.
187
    */
190
    */
188
   struct brw_context *brw = brw_context(ctx);
191
   struct brw_context *brw = brw_context(ctx);
189
   intel_batchbuffer_emit_mi_flush(brw);
192
   intel_batchbuffer_emit_mi_flush(brw);
190
}
193
}