#include "brw_draw.h"
#include "brw_defines.h"
-#include "brw_attrib.h"
#include "brw_context.h"
#include "brw_aub.h"
#include "brw_state.h"
#include "intel_batchbuffer.h"
#include "intel_buffer_objects.h"
-
-
+#include "tnl/tnl.h"
+#include "vbo/vbo_context.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
static void brw_emit_prim( struct brw_context *brw,
- const struct vbo_prim *prim )
+ const struct _mesa_prim *prim )
{
struct brw_3d_primitive prim_packet;
}
}
-
-
-static void update_current_size( struct gl_client_array *array)
-{
- const GLfloat *ptr = (const GLfloat *)array->Ptr;
-
- assert(array->StrideB == 0);
- assert(array->Type == GL_FLOAT || array->Type == GL_UNSIGNED_BYTE);
-
- if (ptr[3] != 1.0)
- array->Size = 4;
- else if (ptr[2] != 0.0)
- array->Size = 3;
- else if (ptr[1] != 0.0)
- array->Size = 2;
- else
- array->Size = 1;
-}
-
-
-
-/* Fill in any gaps in passed arrays with pointers to current
- * attributes:
- */
static void brw_merge_inputs( struct brw_context *brw,
const struct gl_client_array *arrays[])
{
- struct gl_client_array *current_values = brw->vb.current_values;
struct brw_vertex_element *inputs = brw->vb.inputs;
struct brw_vertex_info old = brw->vb.info;
GLuint i;
memset(inputs, 0, sizeof(*inputs));
memset(&brw->vb.info, 0, sizeof(brw->vb.info));
- for (i = 0; i < BRW_ATTRIB_MAX; i++) {
- if (arrays[i] && arrays[i]->Enabled)
- {
- brw->vb.inputs[i].glarray = arrays[i];
- brw->vb.info.varying |= 1 << i;
- }
- else
- {
- brw->vb.inputs[i].glarray = ¤t_values[i];
- update_current_size(¤t_values[i]);
- }
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ brw->vb.inputs[i].glarray = arrays[i];
+
+ /* XXX: metaops passes null arrays */
+ if (arrays[i]) {
+ if (arrays[i]->StrideB != 0)
+ brw->vb.info.varying |= 1 << i;
- brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
+ brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
+ }
}
/* Raise statechanges if input sizes and varying have changed:
brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
}
+/* XXX: could split the primitive list to fallback only on the
+ * non-conformant primitives.
+ */
static GLboolean check_fallbacks( struct brw_context *brw,
- const struct vbo_prim *prim,
+ const struct _mesa_prim *prim,
GLuint nr_prims )
{
GLuint i;
return GL_FALSE;
}
-
+/* May fail if out of video memory for texture or vbo upload, or on
+ * fallback conditions.
+ */
static GLboolean brw_try_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
- const struct vbo_prim *prim,
+ const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLuint min_index,
if (ctx->NewState)
_mesa_update_state( ctx );
-
+
/* Bind all inputs, derive varying and size information:
*/
brw_merge_inputs( brw, arrays );
-
+
/* Have to validate state quite late. Will rebuild tnl_program,
* which depends on varying information.
*
}
{
- assert(intel->locked);
-
-
-
/* Set the first primitive early, ahead of validate_state:
*/
brw_set_prim(brw, prim[0].mode);
return retval;
}
+static GLboolean brw_need_rebase( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index )
+{
+ if (min_index == 0)
+ return GL_FALSE;
+
+ if (ib) {
+ if (!vbo_all_varyings_in_vbos(arrays))
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+ else {
+ /* Hmm. This isn't quite what I wanted. BRW can actually
+ * handle the mixed case well enough that we shouldn't need to
+ * rebase. However, it's probably not very common, nor hugely
+ * expensive to do it this way:
+ */
+ if (!vbo_all_varyings_in_vbos(arrays))
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+}
+
void brw_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
- const struct vbo_prim *prim,
+ const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
GLuint min_index,
struct intel_context *intel = intel_context(ctx);
GLboolean retval;
+ /* Decide if we want to rebase. If so we end up recursing once
+ * only into this function.
+ */
+ if (brw_need_rebase( ctx, arrays, ib, min_index )) {
+ vbo_rebase_prims( ctx, arrays,
+ prim, nr_prims,
+ ib, min_index, max_index,
+ brw_draw_prims );
+
+ return;
+ }
+
+
+ /* Make a first attempt at drawing:
+ */
retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
* fragmented. Clear out all heaps and start from scratch by
* faking a contended lock event: (done elsewhere)
*/
- if (!retval && bmError(intel)) {
+ if (!retval && !intel->Fallback && bmError(intel)) {
DBG("retrying\n");
/* Then try a second time only to upload textures and draw the
* primitives:
* swrast to do the drawing.
*/
if (!retval) {
- brw_fallback();
+ _swsetup_Wakeup(ctx);
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
- brw_unfallback();
}
if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) {
void brw_draw_init( struct brw_context *brw )
{
GLcontext *ctx = &brw->intel.ctx;
+ struct vbo_context *vbo = vbo_context(ctx);
GLuint i;
+ /* Register our drawing function:
+ */
+ vbo->draw_prims = brw_draw_prims;
+
brw->vb.upload.size = BRW_UPLOAD_INIT_SIZE;
for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) {
brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
- /* XXX: Set these to no-backing-store
+ /* NOTE: These are set to no-backing-store.
*/
bmBufferSetInvalidateCB(&brw->intel,
intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])),
brw_invalidate_vbo_cb,
&brw->intel,
GL_TRUE);
-
}
ctx->Driver.BufferData( ctx,
NULL,
GL_DYNAMIC_DRAW_ARB,
brw->vb.upload.vbo[0] );
-
-
- brw_init_current_values(ctx, brw->vb.current_values);
}
void brw_draw_destroy( struct brw_context *brw )