Compare commits

...

3 Commits

Author SHA1 Message Date
Jordan Justen
c7e77fcc31 i965: use cut index to handle primitive restart when possible
If the primitive restart index and the primitive type can
be handled by the cut index feature, then use the hardware
to handle the primitive restart feature.

The VBO module's software handling of primitive restart is
used as a fall back.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-05-17 10:55:00 -07:00
Jordan Justen
5a13d321ff i965: add flag to enable cut_index
When brw->prim_restart.enable_cut_index is set, the cut index
will be enabled when uploading index_buffer commands.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-05-17 10:55:00 -07:00
Jordan Justen
c7ecc2e46c i965: create code path to handle primitive restart in hardware
For newer hardware we disable the VBO module's software handling
of primitive restart. We now handle primitive restarts in
brw_handle_primitive_restart.

The initial version of brw_handle_primitive_restart simply calls
vbo_sw_primitive_restart, and therefore still uses the VBO
module software primitive restart support.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-05-17 10:55:00 -07:00
10 changed files with 204 additions and 2 deletions

View File

@@ -46,7 +46,7 @@ GLSL 1.40 missing: UBOS, inverse(),
highp change
Instanced drawing (GL_ARB_draw_instanced) DONE (i965, gallium, swrast)
Buffer copying (GL_ARB_copy_buffer) DONE (i965, r300, r600, swrast)
Primitive restart (GL_NV_primitive_restart) DONE (r600)
Primitive restart (GL_NV_primitive_restart) DONE (i965, r600)
16 vertex texture image units DONE
Texture buffer objs (GL_ARB_texture_buffer_object) needs GL3.1 enabling (i965)
Rectangular textures (GL_ARB_texture_rectangle) DONE (i965, r300, r600, swrast)

View File

@@ -55,6 +55,7 @@ i965_C_FILES = \
brw_misc_state.c \
brw_optimize.c \
brw_program.c \
brw_primitive_restart.c \
brw_queryobj.c \
brw_sf.c \
brw_sf_emit.c \

View File

@@ -295,6 +295,9 @@ brwCreateContext(int api,
brw->has_negative_rhw_bug = true;
}
brw->prim_restart.in_progress = false;
brw->prim_restart.enable_cut_index = false;
brw_init_state( brw );
brw->curbe.last_buf = calloc(1, 4096);

View File

@@ -1001,6 +1001,12 @@ struct brw_context
uint32_t render_target_format[MESA_FORMAT_COUNT];
bool format_supported_as_render_target[MESA_FORMAT_COUNT];
/* PrimitiveRestart */
struct {
bool in_progress;
bool enable_cut_index;
} prim_restart;
};

View File

@@ -167,6 +167,8 @@
#define BRW_SPRITE_POINT_ENABLE 16
#define BRW_CUT_INDEX_ENABLE (1 << 10)
#define BRW_INDEX_BYTE 0
#define BRW_INDEX_WORD 1
#define BRW_INDEX_DWORD 2

View File

@@ -545,6 +545,12 @@ void brw_draw_prims( struct gl_context *ctx,
if (!_mesa_check_conditional_render(ctx))
return;
/* Handle primitive restart if needed */
if (brw_handle_primitive_restart(ctx, prim, nr_prims, ib)) {
/* The draw was handled, so we can exit now */
return;
}
if (!vbo_all_varyings_in_vbos(arrays)) {
if (!index_bounds_valid)
vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);

View File

@@ -51,4 +51,11 @@ void brw_draw_destroy( struct brw_context *brw );
void brw_init_current_values(struct gl_context *ctx,
struct gl_client_array *arrays);
/* brw_primitive_restart.c */
GLboolean
brw_handle_primitive_restart(struct gl_context *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib);
#endif

View File

@@ -851,13 +851,20 @@ static void brw_emit_index_buffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
const struct _mesa_index_buffer *index_buffer = brw->ib.ib;
GLuint cut_index_setting;
if (index_buffer == NULL)
return;
if (brw->prim_restart.enable_cut_index) {
cut_index_setting = BRW_CUT_INDEX_ENABLE;
} else {
cut_index_setting = 0;
}
BEGIN_BATCH(3);
OUT_BATCH(CMD_INDEX_BUFFER << 16 |
/* cut index enable << 10 */
cut_index_setting |
get_index_type(index_buffer->type) << 8 |
1);
OUT_RELOC(brw->ib.bo,

View File

@@ -0,0 +1,166 @@
/*
* Copyright © 2012 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Jordan Justen <jordan.l.justen@intel.com>
*
*/
#include "main/imports.h"
#include "main/bufferobj.h"
#include "brw_context.h"
#include "brw_draw.h"
/**
* Check if the hardware's cut index support can handle the primitive
* restart index value.
*/
static bool
can_cut_index_handle_restart_index(struct gl_context *ctx,
const struct _mesa_index_buffer *ib)
{
bool cut_index_will_work;
switch (ib->type) {
case GL_UNSIGNED_BYTE:
cut_index_will_work = (ctx->Array.RestartIndex & 0xff) == 0xff;
break;
case GL_UNSIGNED_SHORT:
cut_index_will_work = (ctx->Array.RestartIndex & 0xffff) == 0xffff;
break;
case GL_UNSIGNED_INT:
cut_index_will_work = ctx->Array.RestartIndex == 0xffffffff;
break;
default:
cut_index_will_work = false;
assert(0);
}
return cut_index_will_work;
}
/**
* Check if the hardware's cut index support can handle the primitive
* restart case.
*/
static bool
can_cut_index_handle_prims(struct gl_context *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib)
{
if (!can_cut_index_handle_restart_index(ctx, ib)) {
/* The primitive restart index can't be handled, so take
* the software path
*/
return false;
}
for ( ; nr_prims > 0; nr_prims--) {
switch(prim->mode) {
case GL_POINTS:
case GL_LINES:
case GL_LINE_STRIP:
case GL_TRIANGLES:
case GL_TRIANGLE_STRIP:
/* Cut index supports these primitive types */
break;
default:
/* Cut index does not support these primitive types */
//case GL_LINE_LOOP:
//case GL_TRIANGLE_FAN:
//case GL_QUADS:
//case GL_QUAD_STRIP:
//case GL_POLYGON:
return false;
}
}
return true;
}
/**
* Check if primitive restart is enabled, and if so, handle it properly.
*
* In some cases the support will be handled in software. When available
* hardware will handle primitive restart.
*/
GLboolean
brw_handle_primitive_restart(struct gl_context *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib)
{
struct brw_context *brw = brw_context(ctx);
/* We only need to handle cases where there is an index buffer. */
if (ib == NULL) {
return GL_FALSE;
}
/* If the driver has requested software handling of primitive restarts,
* then the VBO module has already taken care of things, and we can
* just draw as normal.
*/
if (ctx->Const.PrimitiveRestartInSoftware) {
return GL_FALSE;
}
/* If we have set the in_progress flag, then we are in the middle
* of handling the primitive restart draw.
*/
if (brw->prim_restart.in_progress) {
return GL_FALSE;
}
/* If PrimitiveRestart is not enabled, then we aren't concerned about
* handling this draw.
*/
if (!(ctx->Array.PrimitiveRestart)) {
return GL_FALSE;
}
/* Signal that we are in the process of handling the
* primitive restart draw
*/
brw->prim_restart.in_progress = true;
if (can_cut_index_handle_prims(ctx, prim, nr_prims, ib)) {
/* Cut index should work for primitive restart, so use it
*/
brw->prim_restart.enable_cut_index = true;
brw_draw_prims(ctx, prim, nr_prims, ib, GL_FALSE, -1, -1, NULL);
brw->prim_restart.enable_cut_index = false;
} else {
/* Not all the primitive draw modes are supported by the cut index,
* so take the software path
*/
vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
}
brw->prim_restart.in_progress = false;
/* The primitive restart draw was completed, so return true. */
return GL_TRUE;
}

4
src/mesa/drivers/dri/intel/intel_extensions.c Normal file → Executable file
View File

@@ -167,4 +167,8 @@ intelInitExtensions(struct gl_context *ctx)
else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
ctx->Extensions.EXT_texture_compression_s3tc = true;
}
if (intel->gen >= 4) {
ctx->Extensions.NV_primitive_restart = true;
}
}