Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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