i965g: more work on compiling, particularly the brw_draw files
This commit is contained in:
parent
4f7931bb35
commit
4dd2f6640b
|
@ -69,6 +69,7 @@
|
||||||
#include "util/u_stream.h"
|
#include "util/u_stream.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
#include "util/u_tile.h"
|
#include "util/u_tile.h"
|
||||||
|
#include "util/u_prim.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
|
#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
|
||||||
|
@ -600,6 +601,32 @@ const char *pf_name( enum pipe_format format )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const struct debug_named_value pipe_prim_names[] = {
|
||||||
|
#ifdef DEBUG
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_LINES),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP),
|
||||||
|
DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON),
|
||||||
|
#endif
|
||||||
|
DEBUG_NAMED_VALUE_END
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char *u_prim_name( unsigned prim )
|
||||||
|
{
|
||||||
|
return debug_dump_enum(pipe_prim_names, prim);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void debug_dump_image(const char *prefix,
|
void debug_dump_image(const char *prefix,
|
||||||
unsigned format, unsigned cpp,
|
unsigned format, unsigned cpp,
|
||||||
|
|
|
@ -135,4 +135,6 @@ static INLINE unsigned u_reduced_prim( unsigned pipe_prim )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *u_prim_name( unsigned pipe_prim );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#ifndef U_UPLOAD_MGR_H
|
#ifndef U_UPLOAD_MGR_H
|
||||||
#define U_UPLOAD_MGR_H
|
#define U_UPLOAD_MGR_H
|
||||||
|
|
||||||
|
#include "pipe/p_error.h"
|
||||||
|
|
||||||
struct pipe_screen;
|
struct pipe_screen;
|
||||||
struct pipe_buffer;
|
struct pipe_buffer;
|
||||||
struct u_upload_mgr;
|
struct u_upload_mgr;
|
||||||
|
|
|
@ -61,7 +61,7 @@ C_SOURCES = \
|
||||||
brw_wm_state.c \
|
brw_wm_state.c \
|
||||||
brw_wm_surface_state.c \
|
brw_wm_surface_state.c \
|
||||||
brw_bo.c \
|
brw_bo.c \
|
||||||
intel_batchbuffer.c \
|
brw_batchbuffer.c \
|
||||||
intel_tex_layout.c
|
intel_tex_layout.c
|
||||||
|
|
||||||
include ../../Makefile.template
|
include ../../Makefile.template
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "brw_batchbuffer.h"
|
||||||
|
#include "brw_decode.h"
|
||||||
|
#include "brw_reg.h"
|
||||||
|
#include "brw_winsys.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
brw_batchbuffer_reset(struct brw_batchbuffer *batch)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = batch->intel;
|
||||||
|
|
||||||
|
if (batch->buf != NULL) {
|
||||||
|
brw->sws->bo_unreference(batch->buf);
|
||||||
|
batch->buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!batch->buffer && intel->ttm == GL_TRUE)
|
||||||
|
batch->buffer = malloc (intel->maxBatchSize);
|
||||||
|
|
||||||
|
batch->buf = batch->sws->bo_alloc(batch->sws,
|
||||||
|
BRW_BUFFER_TYPE_BATCH,
|
||||||
|
intel->maxBatchSize, 4096);
|
||||||
|
if (batch->buffer)
|
||||||
|
batch->map = batch->buffer;
|
||||||
|
else {
|
||||||
|
batch->sws->bo_map(batch->buf, GL_TRUE);
|
||||||
|
batch->map = batch->buf->virtual;
|
||||||
|
}
|
||||||
|
batch->size = intel->maxBatchSize;
|
||||||
|
batch->ptr = batch->map;
|
||||||
|
batch->dirty_state = ~0;
|
||||||
|
batch->cliprect_mode = IGNORE_CLIPRECTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct brw_batchbuffer *
|
||||||
|
brw_batchbuffer_alloc(struct brw_winsys_screen *sws)
|
||||||
|
{
|
||||||
|
struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer);
|
||||||
|
|
||||||
|
batch->sws = sws;
|
||||||
|
brw_batchbuffer_reset(batch);
|
||||||
|
|
||||||
|
return batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
brw_batchbuffer_free(struct brw_batchbuffer *batch)
|
||||||
|
{
|
||||||
|
if (batch->map) {
|
||||||
|
dri_bo_unmap(batch->buf);
|
||||||
|
batch->map = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
brw->sws->bo_unreference(batch->buf);
|
||||||
|
batch->buf = NULL;
|
||||||
|
FREE(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = batch->intel;
|
||||||
|
GLuint used = batch->ptr - batch->map;
|
||||||
|
|
||||||
|
if (used == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (intel->first_post_swapbuffers_batch == NULL) {
|
||||||
|
intel->first_post_swapbuffers_batch = intel->batch->buf;
|
||||||
|
batch->sws->bo_reference(intel->first_post_swapbuffers_batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intel->first_post_swapbuffers_batch == NULL) {
|
||||||
|
intel->first_post_swapbuffers_batch = intel->batch->buf;
|
||||||
|
batch->sws->bo_reference(intel->first_post_swapbuffers_batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_BATCH)
|
||||||
|
fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
|
||||||
|
used);
|
||||||
|
|
||||||
|
/* Emit a flush if the bufmgr doesn't do it for us. */
|
||||||
|
if (intel->always_flush_cache || !intel->ttm) {
|
||||||
|
*(GLuint *) (batch->ptr) = intel->vtbl.flush_cmd();
|
||||||
|
batch->ptr += 4;
|
||||||
|
used = batch->ptr - batch->map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round batchbuffer usage to 2 DWORDs. */
|
||||||
|
|
||||||
|
if ((used & 4) == 0) {
|
||||||
|
*(GLuint *) (batch->ptr) = 0; /* noop */
|
||||||
|
batch->ptr += 4;
|
||||||
|
used = batch->ptr - batch->map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the end of the buffer. */
|
||||||
|
*(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; /* noop */
|
||||||
|
batch->ptr += 4;
|
||||||
|
used = batch->ptr - batch->map;
|
||||||
|
|
||||||
|
batch->sws->bo_unmap(batch->buf);
|
||||||
|
|
||||||
|
batch->map = NULL;
|
||||||
|
batch->ptr = NULL;
|
||||||
|
|
||||||
|
batch->sws->bo_exec(batch->buf, used, NULL, 0, 0 );
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_BATCH) {
|
||||||
|
dri_bo_map(batch->buf, GL_FALSE);
|
||||||
|
intel_decode(batch->buf->virtual, used / 4, batch->buf->offset,
|
||||||
|
brw->brw_screen->pci_id);
|
||||||
|
dri_bo_unmap(batch->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_SYNC) {
|
||||||
|
fprintf(stderr, "waiting for idle\n");
|
||||||
|
dri_bo_map(batch->buf, GL_TRUE);
|
||||||
|
dri_bo_unmap(batch->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the buffer:
|
||||||
|
*/
|
||||||
|
brw_batchbuffer_reset(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the only way buffers get added to the validate list.
|
||||||
|
*/
|
||||||
|
GLboolean
|
||||||
|
brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
|
||||||
|
struct brw_winsys_buffer *buffer,
|
||||||
|
uint32_t read_domains, uint32_t write_domain,
|
||||||
|
uint32_t delta)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (batch->ptr - batch->map > batch->buf->size)
|
||||||
|
_mesa_printf ("bad relocation ptr %p map %p offset %d size %d\n",
|
||||||
|
batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
|
||||||
|
|
||||||
|
ret = batch->sws->bo_emit_reloc(batch->buf,
|
||||||
|
read_domains,
|
||||||
|
write_domain,
|
||||||
|
delta,
|
||||||
|
batch->ptr - batch->map,
|
||||||
|
buffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using the old buffer offset, write in what the right data would be, in case
|
||||||
|
* the buffer doesn't move and we can short-circuit the relocation processing
|
||||||
|
* in the kernel
|
||||||
|
*/
|
||||||
|
brw_batchbuffer_emit_dword (batch, buffer->offset + delta);
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
brw_batchbuffer_data(struct brw_batchbuffer *batch,
|
||||||
|
const void *data, GLuint bytes,
|
||||||
|
enum cliprect_mode cliprect_mode)
|
||||||
|
{
|
||||||
|
assert((bytes & 3) == 0);
|
||||||
|
brw_batchbuffer_require_space(batch, bytes);
|
||||||
|
__memcpy(batch->ptr, data, bytes);
|
||||||
|
batch->ptr += bytes;
|
||||||
|
}
|
|
@ -33,14 +33,12 @@ void brw_batchbuffer_reset(struct brw_batchbuffer *batch);
|
||||||
* Consider it a convenience function wrapping multple
|
* Consider it a convenience function wrapping multple
|
||||||
* intel_buffer_dword() calls.
|
* intel_buffer_dword() calls.
|
||||||
*/
|
*/
|
||||||
void brw_batchbuffer_data(struct brw_batchbuffer *batch,
|
int brw_batchbuffer_data(struct brw_batchbuffer *batch,
|
||||||
const void *data, GLuint bytes,
|
const void *data, GLuint bytes,
|
||||||
enum cliprect_mode cliprect_mode);
|
enum cliprect_mode cliprect_mode);
|
||||||
|
|
||||||
void brw_batchbuffer_release_space(struct brw_batchbuffer *batch,
|
|
||||||
GLuint bytes);
|
|
||||||
|
|
||||||
GLboolean brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
|
int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
|
||||||
struct brw_winsys_buffer *buffer,
|
struct brw_winsys_buffer *buffer,
|
||||||
uint32_t read_domains,
|
uint32_t read_domains,
|
||||||
uint32_t write_domain,
|
uint32_t write_domain,
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void calc_sane_viewport( const struct pipe_viewport_state *vp,
|
||||||
svp->far = 1;
|
svp->far = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_cc_vp( struct brw_context *brw )
|
static int prepare_cc_vp( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
struct brw_cc_viewport ccv;
|
struct brw_cc_viewport ccv;
|
||||||
struct sane_viewport svp;
|
struct sane_viewport svp;
|
||||||
|
@ -72,6 +72,8 @@ static void prepare_cc_vp( struct brw_context *brw )
|
||||||
|
|
||||||
brw->sws->bo_unreference(brw->cc.vp_bo);
|
brw->sws->bo_unreference(brw->cc.vp_bo);
|
||||||
brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
|
brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_cc_vp = {
|
const struct brw_tracked_state brw_cc_vp = {
|
||||||
|
@ -158,7 +160,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key)
|
||||||
return bo;
|
return bo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_cc_unit( struct brw_context *brw )
|
static int prepare_cc_unit( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
struct brw_cc_unit_key key;
|
struct brw_cc_unit_key key;
|
||||||
|
|
||||||
|
@ -172,6 +174,8 @@ static void prepare_cc_unit( struct brw_context *brw )
|
||||||
|
|
||||||
if (brw->cc.state_bo == NULL)
|
if (brw->cc.state_bo == NULL)
|
||||||
brw->cc.state_bo = cc_unit_create_from_key(brw, &key);
|
brw->cc.state_bo = cc_unit_create_from_key(brw, &key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_cc_unit = {
|
const struct brw_tracked_state brw_cc_unit = {
|
||||||
|
|
|
@ -146,7 +146,7 @@ static void compile_clip_prog( struct brw_context *brw,
|
||||||
|
|
||||||
/* Calculate interpolants for triangle and line rasterization.
|
/* Calculate interpolants for triangle and line rasterization.
|
||||||
*/
|
*/
|
||||||
static void upload_clip_prog(struct brw_context *brw)
|
static int upload_clip_prog(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
struct brw_clip_prog_key key;
|
struct brw_clip_prog_key key;
|
||||||
|
|
||||||
|
@ -173,6 +173,8 @@ static void upload_clip_prog(struct brw_context *brw)
|
||||||
&brw->clip.prog_data);
|
&brw->clip.prog_data);
|
||||||
if (brw->clip.prog_bo == NULL)
|
if (brw->clip.prog_bo == NULL)
|
||||||
compile_clip_prog( brw, &key );
|
compile_clip_prog( brw, &key );
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ clip_unit_create_from_key(struct brw_context *brw,
|
||||||
return bo;
|
return bo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void upload_clip_unit( struct brw_context *brw )
|
static int upload_clip_unit( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
struct brw_clip_unit_key key;
|
struct brw_clip_unit_key key;
|
||||||
|
|
||||||
|
@ -173,6 +173,8 @@ static void upload_clip_unit( struct brw_context *brw )
|
||||||
if (brw->clip.state_bo == NULL) {
|
if (brw->clip.state_bo == NULL) {
|
||||||
brw->clip.state_bo = clip_unit_create_from_key(brw, &key);
|
brw->clip.state_bo = clip_unit_create_from_key(brw, &key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_clip_unit = {
|
const struct brw_tracked_state brw_clip_unit = {
|
||||||
|
|
|
@ -105,7 +105,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen)
|
||||||
brw->state.dirty.mesa = ~0;
|
brw->state.dirty.mesa = ~0;
|
||||||
brw->state.dirty.brw = ~0;
|
brw->state.dirty.brw = ~0;
|
||||||
|
|
||||||
brw->emit_state_always = 0;
|
brw->flags.always_emit_state = 0;
|
||||||
|
|
||||||
make_empty_list(&brw->query.active_head);
|
make_empty_list(&brw->query.active_head);
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,8 @@ struct brw_fragment_shader {
|
||||||
#define PIPE_NEW_FRAGMENT_CONSTANTS 0x2
|
#define PIPE_NEW_FRAGMENT_CONSTANTS 0x2
|
||||||
#define PIPE_NEW_VERTEX_CONSTANTS 0x2
|
#define PIPE_NEW_VERTEX_CONSTANTS 0x2
|
||||||
#define PIPE_NEW_CLIP 0x2
|
#define PIPE_NEW_CLIP 0x2
|
||||||
|
#define PIPE_NEW_INDEX_BUFFER 0x2
|
||||||
|
#define PIPE_NEW_INDEX_RANGE 0x2
|
||||||
|
|
||||||
|
|
||||||
#define BRW_NEW_URB_FENCE 0x1
|
#define BRW_NEW_URB_FENCE 0x1
|
||||||
|
@ -387,8 +389,8 @@ struct brw_cache {
|
||||||
*/
|
*/
|
||||||
struct brw_tracked_state {
|
struct brw_tracked_state {
|
||||||
struct brw_state_flags dirty;
|
struct brw_state_flags dirty;
|
||||||
void (*prepare)( struct brw_context *brw );
|
int (*prepare)( struct brw_context *brw );
|
||||||
void (*emit)( struct brw_context *brw );
|
int (*emit)( struct brw_context *brw );
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Flags for brw->state.cache.
|
/* Flags for brw->state.cache.
|
||||||
|
@ -465,9 +467,7 @@ struct brw_context
|
||||||
GLuint primitive;
|
GLuint primitive;
|
||||||
GLuint reduced_primitive;
|
GLuint reduced_primitive;
|
||||||
|
|
||||||
GLboolean emit_state_always;
|
/* Active state from the state tracker:
|
||||||
|
|
||||||
/* Active vertex program:
|
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
const struct brw_vertex_shader *vertex_shader;
|
const struct brw_vertex_shader *vertex_shader;
|
||||||
|
@ -475,11 +475,31 @@ struct brw_context
|
||||||
const struct brw_blend_state *blend;
|
const struct brw_blend_state *blend;
|
||||||
const struct brw_rasterizer_state *rast;
|
const struct brw_rasterizer_state *rast;
|
||||||
const struct brw_depth_stencil_alpha_state *zstencil;
|
const struct brw_depth_stencil_alpha_state *zstencil;
|
||||||
|
|
||||||
|
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
||||||
|
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||||
|
unsigned num_vertex_elements;
|
||||||
|
unsigned num_vertex_buffers;
|
||||||
|
|
||||||
struct pipe_framebuffer_state fb;
|
struct pipe_framebuffer_state fb;
|
||||||
struct pipe_viewport_state vp;
|
struct pipe_viewport_state vp;
|
||||||
struct pipe_clip_state ucp;
|
struct pipe_clip_state ucp;
|
||||||
struct pipe_buffer *vertex_constants;
|
struct pipe_buffer *vertex_constants;
|
||||||
struct pipe_buffer *fragment_constants;
|
struct pipe_buffer *fragment_constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index buffer for this draw_prims call.
|
||||||
|
*
|
||||||
|
* Updates are signaled by PIPE_NEW_INDEX_BUFFER.
|
||||||
|
*/
|
||||||
|
struct pipe_buffer *index_buffer;
|
||||||
|
unsigned index_size;
|
||||||
|
|
||||||
|
/* Updates are signalled by PIPE_NEW_INDEX_RANGE:
|
||||||
|
*/
|
||||||
|
unsigned min_index;
|
||||||
|
unsigned max_index;
|
||||||
|
|
||||||
} curr;
|
} curr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -504,30 +524,26 @@ struct brw_context
|
||||||
struct brw_cached_batch_item *cached_batch_items;
|
struct brw_cached_batch_item *cached_batch_items;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
|
||||||
unsigned num_vertex_element;
|
|
||||||
unsigned num_vertex_buffer;
|
|
||||||
|
|
||||||
struct u_upload_mgr *upload_vertex;
|
struct u_upload_mgr *upload_vertex;
|
||||||
struct u_upload_mgr *upload_index;
|
struct u_upload_mgr *upload_index;
|
||||||
|
|
||||||
|
/* Information on uploaded vertex buffers:
|
||||||
/* Summary of size and varying of active arrays, so we can check
|
|
||||||
* for changes to this state:
|
|
||||||
*/
|
*/
|
||||||
struct brw_vertex_info info;
|
struct {
|
||||||
unsigned int min_index, max_index;
|
unsigned stride; /* in bytes between successive vertices */
|
||||||
|
unsigned offset; /* in bytes, of first vertex in bo */
|
||||||
|
unsigned vertex_count; /* count of valid vertices which may be accessed */
|
||||||
|
struct brw_winsys_buffer *bo;
|
||||||
|
} vb[PIPE_MAX_ATTRIBS];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
} ve[PIPE_MAX_ATTRIBS];
|
||||||
|
|
||||||
|
unsigned nr_vb; /* currently the same as curr.num_vertex_buffers */
|
||||||
|
unsigned nr_ve; /* currently the same as curr.num_vertex_elements */
|
||||||
} vb;
|
} vb;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/**
|
|
||||||
* Index buffer for this draw_prims call.
|
|
||||||
*
|
|
||||||
* Updates are signaled by BRW_NEW_INDICES.
|
|
||||||
*/
|
|
||||||
const struct _mesa_index_buffer *ib;
|
|
||||||
|
|
||||||
/* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */
|
/* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */
|
||||||
struct brw_winsys_buffer *bo;
|
struct brw_winsys_buffer *bo;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
@ -668,6 +684,14 @@ struct brw_context
|
||||||
int index;
|
int index;
|
||||||
GLboolean active;
|
GLboolean active;
|
||||||
} query;
|
} query;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned always_emit_state:1;
|
||||||
|
unsigned always_flush_batch:1;
|
||||||
|
unsigned force_swtnl:1;
|
||||||
|
unsigned no_swtnl:1;
|
||||||
|
} flags;
|
||||||
|
|
||||||
/* Used to give every program string a unique id
|
/* Used to give every program string a unique id
|
||||||
*/
|
*/
|
||||||
GLuint program_id;
|
GLuint program_id;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
* constants. That greatly reduces the demand for space in the CURBE.
|
* constants. That greatly reduces the demand for space in the CURBE.
|
||||||
* Some of the comments within are dated...
|
* Some of the comments within are dated...
|
||||||
*/
|
*/
|
||||||
static void calculate_curbe_offsets( struct brw_context *brw )
|
static int calculate_curbe_offsets( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
/* CACHE_NEW_WM_PROG */
|
/* CACHE_NEW_WM_PROG */
|
||||||
const GLuint nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16;
|
const GLuint nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16;
|
||||||
|
@ -104,6 +104,8 @@ static void calculate_curbe_offsets( struct brw_context *brw )
|
||||||
|
|
||||||
brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS;
|
brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +159,7 @@ static GLfloat fixed_plane[6][4] = {
|
||||||
* cache mechanism, but maybe would benefit from a comparison against
|
* cache mechanism, but maybe would benefit from a comparison against
|
||||||
* the current uploaded set of constants.
|
* the current uploaded set of constants.
|
||||||
*/
|
*/
|
||||||
static void prepare_constant_buffer(struct brw_context *brw)
|
static int prepare_constant_buffer(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
const GLuint sz = brw->curbe.total_size;
|
const GLuint sz = brw->curbe.total_size;
|
||||||
const GLuint bufsz = sz * 16 * sizeof(GLfloat);
|
const GLuint bufsz = sz * 16 * sizeof(GLfloat);
|
||||||
|
@ -170,7 +172,7 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||||
brw->curbe.last_buf = NULL;
|
brw->curbe.last_buf = NULL;
|
||||||
brw->curbe.last_bufsz = 0;
|
brw->curbe.last_bufsz = 0;
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = (GLfloat *) CALLOC(bufsz, 1);
|
buf = (GLfloat *) CALLOC(bufsz, 1);
|
||||||
|
@ -305,9 +307,11 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||||
* flushes as necessary when doublebuffering of CURBEs isn't
|
* flushes as necessary when doublebuffering of CURBEs isn't
|
||||||
* possible.
|
* possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_constant_buffer(struct brw_context *brw)
|
static int emit_constant_buffer(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
GLuint sz = brw->curbe.total_size;
|
GLuint sz = brw->curbe.total_size;
|
||||||
|
|
||||||
|
@ -322,6 +326,7 @@ static void emit_constant_buffer(struct brw_context *brw)
|
||||||
(sz - 1) + brw->curbe.curbe_offset);
|
(sz - 1) + brw->curbe.curbe_offset);
|
||||||
}
|
}
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_constant_buffer = {
|
const struct brw_tracked_state brw_constant_buffer = {
|
||||||
|
|
|
@ -26,15 +26,18 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "util/u_prim.h"
|
||||||
|
#include "util/u_upload_mgr.h"
|
||||||
|
|
||||||
#include "brw_draw.h"
|
#include "brw_draw.h"
|
||||||
#include "brw_defines.h"
|
#include "brw_defines.h"
|
||||||
#include "brw_context.h"
|
#include "brw_context.h"
|
||||||
#include "brw_state.h"
|
#include "brw_state.h"
|
||||||
#include "brw_debug.h"
|
#include "brw_debug.h"
|
||||||
|
#include "brw_screen.h"
|
||||||
|
|
||||||
#include "brw_batchbuffer.h"
|
#include "brw_batchbuffer.h"
|
||||||
|
|
||||||
#define FILE_DEBUG_FLAG DEBUG_BATCH
|
|
||||||
|
|
||||||
static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = {
|
static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = {
|
||||||
_3DPRIM_POINTLIST,
|
_3DPRIM_POINTLIST,
|
||||||
|
@ -56,18 +59,21 @@ static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = {
|
||||||
* programs be immune to the active primitive (ie. cope with all
|
* programs be immune to the active primitive (ie. cope with all
|
||||||
* possibilities). That may not be realistic however.
|
* possibilities). That may not be realistic however.
|
||||||
*/
|
*/
|
||||||
static GLuint brw_set_prim(struct brw_context *brw, unsigned prim)
|
static int brw_set_prim(struct brw_context *brw, unsigned prim )
|
||||||
{
|
{
|
||||||
|
|
||||||
if (BRW_DEBUG & DEBUG_PRIMS)
|
if (BRW_DEBUG & DEBUG_PRIMS)
|
||||||
debug_printf("PRIM: %s\n", u_prim_name(prim));
|
debug_printf("PRIM: %s\n", u_prim_name(prim));
|
||||||
|
|
||||||
if (prim != brw->primitive) {
|
if (prim != brw->primitive) {
|
||||||
|
unsigned reduced_prim;
|
||||||
|
|
||||||
brw->primitive = prim;
|
brw->primitive = prim;
|
||||||
brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
|
brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
|
||||||
|
|
||||||
if (reduced_prim[prim] != brw->reduced_primitive) {
|
reduced_prim = u_reduced_prim(prim);
|
||||||
brw->reduced_primitive = reduced_prim[prim];
|
if (reduced_prim != brw->reduced_primitive) {
|
||||||
|
brw->reduced_primitive = reduced_prim;
|
||||||
brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
|
brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,17 +83,14 @@ static GLuint brw_set_prim(struct brw_context *brw, unsigned prim)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static enum pipe_error brw_emit_prim(struct brw_context *brw,
|
static int brw_emit_prim(struct brw_context *brw,
|
||||||
unsigned prim,
|
|
||||||
unsigned start,
|
unsigned start,
|
||||||
unsigned count,
|
unsigned count,
|
||||||
boolean indexed,
|
boolean indexed,
|
||||||
uint32_t hw_prim)
|
uint32_t hw_prim)
|
||||||
{
|
{
|
||||||
struct brw_3d_primitive prim_packet;
|
struct brw_3d_primitive prim_packet;
|
||||||
|
int ret;
|
||||||
if (INTEL_DEBUG & DEBUG_PRIMS)
|
|
||||||
debug_printf("PRIM: %s %d %d\n", u_prim_name(prim), start, count);
|
|
||||||
|
|
||||||
prim_packet.header.opcode = CMD_3D_PRIM;
|
prim_packet.header.opcode = CMD_3D_PRIM;
|
||||||
prim_packet.header.length = sizeof(prim_packet)/4 - 2;
|
prim_packet.header.length = sizeof(prim_packet)/4 - 2;
|
||||||
|
@ -101,7 +104,7 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw,
|
||||||
prim_packet.start_vert_location += brw->ib.start_vertex_offset;
|
prim_packet.start_vert_location += brw->ib.start_vertex_offset;
|
||||||
prim_packet.instance_count = 1;
|
prim_packet.instance_count = 1;
|
||||||
prim_packet.start_instance_location = 0;
|
prim_packet.start_instance_location = 0;
|
||||||
prim_packet.base_vert_location = prim->basevertex;
|
prim_packet.base_vert_location = 0; // prim->basevertex; XXX: add this to gallium
|
||||||
|
|
||||||
|
|
||||||
/* If we're set to always flush, do it before and after the primitive emit.
|
/* If we're set to always flush, do it before and after the primitive emit.
|
||||||
|
@ -109,20 +112,20 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw,
|
||||||
* and missed flushes of the render cache as it heads to other parts of
|
* and missed flushes of the render cache as it heads to other parts of
|
||||||
* the besides the draw code.
|
* the besides the draw code.
|
||||||
*/
|
*/
|
||||||
if (intel->always_flush_cache) {
|
if (0) {
|
||||||
BEGIN_BATCH(1, IGNORE_CLIPRECTS)
|
BEGIN_BATCH(1, IGNORE_CLIPRECTS);
|
||||||
OUT_BATCH(intel->vtbl.flush_cmd());
|
OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
}
|
}
|
||||||
if (prim_packet.verts_per_instance) {
|
if (prim_packet.verts_per_instance) {
|
||||||
ret = brw_batchbuffer_data( brw->intel.batch, &prim_packet,
|
ret = brw_batchbuffer_data( brw->batch, &prim_packet,
|
||||||
sizeof(prim_packet), LOOP_CLIPRECTS);
|
sizeof(prim_packet), LOOP_CLIPRECTS);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (intel->always_flush_cache) {
|
if (0) {
|
||||||
BEGIN_BATCH(1, IGNORE_CLIPRECTS);
|
BEGIN_BATCH(1, IGNORE_CLIPRECTS);
|
||||||
OUT_BATCH(intel->vtbl.flush_cmd());
|
OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,43 +136,23 @@ static enum pipe_error brw_emit_prim(struct brw_context *brw,
|
||||||
/* May fail if out of video memory for texture or vbo upload, or on
|
/* May fail if out of video memory for texture or vbo upload, or on
|
||||||
* fallback conditions.
|
* fallback conditions.
|
||||||
*/
|
*/
|
||||||
static GLboolean brw_try_draw_prims( struct brw_context *brw,
|
static int
|
||||||
const struct gl_client_array *arrays[],
|
try_draw_range_elements(struct brw_context *brw,
|
||||||
const struct _mesa_prim *prim,
|
struct pipe_buffer *index_buffer,
|
||||||
GLuint nr_prims,
|
unsigned hw_prim,
|
||||||
const struct _mesa_index_buffer *ib,
|
unsigned start, unsigned count)
|
||||||
GLuint min_index,
|
|
||||||
GLuint max_index )
|
|
||||||
{
|
{
|
||||||
struct brw_context *brw = brw_context(ctx);
|
int ret;
|
||||||
GLboolean retval = GL_FALSE;
|
|
||||||
GLboolean warn = GL_FALSE;
|
|
||||||
GLboolean first_time = GL_TRUE;
|
|
||||||
uint32_t hw_prim;
|
|
||||||
GLuint i;
|
|
||||||
|
|
||||||
if (ctx->NewState)
|
ret = brw_validate_state(brw);
|
||||||
_mesa_update_state( ctx );
|
if (ret)
|
||||||
|
return ret;
|
||||||
/* Bind all inputs, derive varying and size information:
|
|
||||||
*/
|
|
||||||
brw_merge_inputs( brw, arrays );
|
|
||||||
|
|
||||||
brw->ib.ib = ib;
|
|
||||||
brw->state.dirty.brw |= BRW_NEW_INDICES;
|
|
||||||
|
|
||||||
brw->vb.min_index = min_index;
|
|
||||||
brw->vb.max_index = max_index;
|
|
||||||
brw->state.dirty.brw |= BRW_NEW_VERTICES;
|
|
||||||
|
|
||||||
hw_prim = brw_set_prim(brw, prim[i].mode);
|
|
||||||
|
|
||||||
brw_validate_state(brw);
|
|
||||||
|
|
||||||
/* Check that we can fit our state in with our existing batchbuffer, or
|
/* Check that we can fit our state in with our existing batchbuffer, or
|
||||||
* flush otherwise.
|
* flush otherwise.
|
||||||
*/
|
*/
|
||||||
ret = dri_bufmgr_check_aperture_space(brw->state.validated_bos,
|
ret = brw->sws->check_aperture_space(brw->sws,
|
||||||
|
brw->state.validated_bos,
|
||||||
brw->state.validated_bo_count);
|
brw->state.validated_bo_count);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -178,12 +161,12 @@ static GLboolean brw_try_draw_prims( struct brw_context *brw,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = brw_emit_prim(brw, &prim[i], hw_prim);
|
ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (intel->always_flush_batch)
|
if (brw->flags.always_flush_batch)
|
||||||
brw_batchbuffer_flush(intel->batch);
|
brw_batchbuffer_flush(brw->batch);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -197,22 +180,45 @@ brw_draw_range_elements(struct pipe_context *pipe,
|
||||||
unsigned max_index,
|
unsigned max_index,
|
||||||
unsigned mode, unsigned start, unsigned count)
|
unsigned mode, unsigned start, unsigned count)
|
||||||
{
|
{
|
||||||
enum pipe_error ret;
|
struct brw_context *brw = brw_context(pipe);
|
||||||
|
int ret;
|
||||||
|
uint32_t hw_prim;
|
||||||
|
|
||||||
if (!vbo_all_varyings_in_vbos(arrays)) {
|
hw_prim = brw_set_prim(brw, mode);
|
||||||
if (!index_bounds_valid)
|
|
||||||
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
|
if (BRW_DEBUG & DEBUG_PRIMS)
|
||||||
|
debug_printf("PRIM: %s %d %d\n", u_prim_name(mode), start, count);
|
||||||
|
|
||||||
|
/* Potentially trigger upload of new index buffer.
|
||||||
|
*
|
||||||
|
* XXX: do we need to go through state validation to achieve this?
|
||||||
|
* Could just call upload code directly.
|
||||||
|
*/
|
||||||
|
if (brw->curr.index_buffer != index_buffer) {
|
||||||
|
pipe_buffer_reference( &brw->curr.index_buffer, index_buffer );
|
||||||
|
brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX: do we really care?
|
||||||
|
*/
|
||||||
|
if (brw->curr.min_index != min_index ||
|
||||||
|
brw->curr.max_index != max_index)
|
||||||
|
{
|
||||||
|
brw->curr.min_index = min_index;
|
||||||
|
brw->curr.max_index = max_index;
|
||||||
|
brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Make a first attempt at drawing:
|
/* Make a first attempt at drawing:
|
||||||
*/
|
*/
|
||||||
ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
|
||||||
|
|
||||||
/* Otherwise, flush and retry:
|
/* Otherwise, flush and retry:
|
||||||
*/
|
*/
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
brw_batchbuffer_flush(intel->batch);
|
brw_batchbuffer_flush(brw->batch);
|
||||||
ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,28 +248,37 @@ brw_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void brw_draw_init( struct brw_context *brw )
|
boolean brw_draw_init( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
/* Register our drawing function:
|
/* Register our drawing function:
|
||||||
*/
|
*/
|
||||||
brw->base.draw_arrays = brw_draw_arrays;
|
brw->base.draw_arrays = brw_draw_arrays;
|
||||||
brw->base.draw_elements = brw_draw_elements;
|
brw->base.draw_elements = brw_draw_elements;
|
||||||
brw->base.draw_range_elements = brw_draw_range_elements;
|
brw->base.draw_range_elements = brw_draw_range_elements;
|
||||||
|
|
||||||
|
/* Create helpers for uploading data in user buffers:
|
||||||
|
*/
|
||||||
|
brw->vb.upload_vertex = u_upload_create( &brw->brw_screen->base,
|
||||||
|
128 * 1024,
|
||||||
|
64,
|
||||||
|
PIPE_BUFFER_USAGE_VERTEX );
|
||||||
|
if (brw->vb.upload_vertex == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
brw->vb.upload_index = u_upload_create( &brw->brw_screen->base,
|
||||||
|
128 * 1024,
|
||||||
|
64,
|
||||||
|
PIPE_BUFFER_USAGE_INDEX );
|
||||||
|
if (brw->vb.upload_index == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void brw_draw_destroy( struct brw_context *brw )
|
void brw_draw_cleanup( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
int i;
|
u_upload_destroy( brw->vb.upload_vertex );
|
||||||
|
u_upload_destroy( brw->vb.upload_index );
|
||||||
if (brw->vb.upload.bo != NULL) {
|
|
||||||
brw->sws->bo_unreference(brw->vb.upload.bo);
|
|
||||||
brw->vb.upload.bo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
|
|
||||||
brw->sws->bo_unreference(brw->vb.inputs[i].bo);
|
|
||||||
brw->vb.inputs[i].bo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
brw->sws->bo_unreference(brw->ib.bo);
|
brw->sws->bo_unreference(brw->ib.bo);
|
||||||
brw->ib.bo = NULL;
|
brw->ib.bo = NULL;
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
|
|
||||||
struct brw_context;
|
struct brw_context;
|
||||||
|
|
||||||
|
boolean brw_draw_init( struct brw_context *brw );
|
||||||
void brw_draw_init( struct brw_context *brw );
|
|
||||||
void brw_draw_cleanup( struct brw_context *brw );
|
void brw_draw_cleanup( struct brw_context *brw );
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,21 +26,23 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
|
#include "pipe/p_error.h"
|
||||||
|
|
||||||
#include "util/u_upload_mgr.h"
|
#include "util/u_upload_mgr.h"
|
||||||
|
#include "util/u_math.h"
|
||||||
|
|
||||||
#include "brw_draw.h"
|
#include "brw_draw.h"
|
||||||
#include "brw_defines.h"
|
#include "brw_defines.h"
|
||||||
#include "brw_context.h"
|
#include "brw_context.h"
|
||||||
#include "brw_state.h"
|
#include "brw_state.h"
|
||||||
#include "brw_fallback.h"
|
#include "brw_screen.h"
|
||||||
|
|
||||||
#include "brw_batchbuffer.h"
|
#include "brw_batchbuffer.h"
|
||||||
|
#include "brw_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned brw_translate_surface_format( unsigned id )
|
static unsigned brw_translate_surface_format( unsigned id )
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case PIPE_FORMAT_R64_FLOAT:
|
case PIPE_FORMAT_R64_FLOAT:
|
||||||
|
@ -186,70 +188,136 @@ static unsigned get_index_type(int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int brw_prepare_vertices(struct brw_context *brw)
|
||||||
static boolean brw_prepare_vertices(struct brw_context *brw)
|
|
||||||
{
|
{
|
||||||
GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
|
unsigned int min_index = brw->curr.min_index;
|
||||||
|
unsigned int max_index = brw->curr.max_index;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
const unsigned char *ptr = NULL;
|
int ret;
|
||||||
GLuint interleave = 0;
|
|
||||||
unsigned int min_index = brw->vb.min_index;
|
|
||||||
unsigned int max_index = brw->vb.max_index;
|
|
||||||
|
|
||||||
struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
|
if (BRW_DEBUG & DEBUG_VERTS)
|
||||||
GLuint nr_uploads = 0;
|
debug_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||||
|
|
||||||
/* First build an array of pointers to ve's in vb.inputs_read
|
|
||||||
|
for (i = 0; i < brw->curr.num_vertex_buffers; i++) {
|
||||||
|
struct pipe_vertex_buffer *vb = &brw->curr.vertex_buffer[i];
|
||||||
|
struct brw_winsys_buffer *bo;
|
||||||
|
struct pipe_buffer *upload_buf;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
if (BRW_DEBUG & DEBUG_VERTS)
|
||||||
|
debug_printf("%s vb[%d] user:%d offset:0x%x sz:0x%x stride:0x%x\n",
|
||||||
|
__FUNCTION__, i,
|
||||||
|
brw_buffer_is_user_buffer(vb->buffer),
|
||||||
|
vb->buffer_offset,
|
||||||
|
vb->buffer->size,
|
||||||
|
vb->stride);
|
||||||
|
|
||||||
|
if (brw_buffer_is_user_buffer(vb->buffer)) {
|
||||||
|
|
||||||
|
/* XXX: simplify this. Stop the state trackers from generating
|
||||||
|
* zero-stride buffers & have them use additional constants (or
|
||||||
|
* add support for >1 constant buffer) instead.
|
||||||
*/
|
*/
|
||||||
if (0)
|
|
||||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < brw->vb.num_vertex_buffer; i++) {
|
|
||||||
struct brw_vertex_buffer *vb = brw->vb.vertex_buffer[i];
|
|
||||||
unsigned size = (vb->stride == 0 ?
|
unsigned size = (vb->stride == 0 ?
|
||||||
vb->size :
|
vb->buffer->size - vb->buffer_offset :
|
||||||
vb->stride * (max_index + 1 - min_index));
|
MAX2(vb->buffer->size - vb->buffer_offset,
|
||||||
|
vb->stride * (max_index + 1 - min_index)));
|
||||||
|
|
||||||
|
ret = u_upload_buffer( brw->vb.upload_vertex,
|
||||||
if (brw_is_user_buffer(vb)) {
|
vb->buffer_offset + min_index * vb->stride,
|
||||||
u_upload_buffer( brw->upload_vertex,
|
|
||||||
min_index * vb->stride,
|
|
||||||
size,
|
size,
|
||||||
|
vb->buffer,
|
||||||
&offset,
|
&offset,
|
||||||
&buffer );
|
&upload_buf );
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bo = brw_buffer(upload_buf)->bo;
|
||||||
|
|
||||||
|
assert(offset + size <= bo->size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = 0;
|
offset = vb->buffer_offset;
|
||||||
buffer = vb->buffer;
|
bo = brw_buffer(vb->buffer)->bo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(offset < bo->size);
|
||||||
|
|
||||||
/* Set up post-upload info about this vertex buffer:
|
/* Set up post-upload info about this vertex buffer:
|
||||||
*/
|
*/
|
||||||
input->offset = (unsigned long)offset;
|
brw->vb.vb[i].offset = offset;
|
||||||
input->stride = vb->stride;
|
brw->vb.vb[i].stride = vb->stride;
|
||||||
input->count = count;
|
brw->vb.vb[i].vertex_count = (vb->stride == 0 ?
|
||||||
brw->sws->bo_unreference(input->bo);
|
1 :
|
||||||
input->bo = intel_bufferobj_buffer(intel, intel_buffer,
|
(bo->size - offset) / vb->stride);
|
||||||
INTEL_READ);
|
brw->sws->bo_unreference(brw->vb.vb[i].bo);
|
||||||
brw->sws->bo_reference(input->bo);
|
brw->vb.vb[i].bo = bo;
|
||||||
|
brw->sws->bo_reference(brw->vb.vb[i].bo);
|
||||||
|
|
||||||
assert(input->offset < input->bo->size);
|
/* Don't need to retain this reference. We have a reference on
|
||||||
assert(input->offset + size <= input->bo->size);
|
* the underlying winsys buffer:
|
||||||
|
*/
|
||||||
|
pipe_buffer_reference( &upload_buf, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brw->vb.nr_vb = i;
|
||||||
brw_prepare_query_begin(brw);
|
brw_prepare_query_begin(brw);
|
||||||
|
|
||||||
for (i = 0; i < brw->vb.nr_enabled; i++) {
|
for (i = 0; i < brw->vb.nr_vb; i++) {
|
||||||
struct brw_vertex_element *input = brw->vb.enabled[i];
|
brw_add_validated_bo(brw, brw->vb.vb[i].bo);
|
||||||
|
|
||||||
brw_add_validated_bo(brw, input->bo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void brw_emit_vertices(struct brw_context *brw)
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int brw_emit_vertex_buffers( struct brw_context *brw )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* If the VS doesn't read any inputs (calculating vertex position from
|
||||||
|
* a state variable for some reason, for example), just bail.
|
||||||
|
*
|
||||||
|
* The stale VB state stays in place, but they don't do anything unless
|
||||||
|
* a VE loads from them.
|
||||||
|
*/
|
||||||
|
if (brw->vb.nr_vb == 0) {
|
||||||
|
if (BRW_DEBUG & DEBUG_VERTS)
|
||||||
|
debug_printf("%s: no active vertex buffers\n", __FUNCTION__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Emit VB state packets.
|
||||||
|
*/
|
||||||
|
BEGIN_BATCH(1 + brw->vb.nr_vb * 4, IGNORE_CLIPRECTS);
|
||||||
|
OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
|
||||||
|
((1 + brw->vb.nr_vb * 4) - 2));
|
||||||
|
|
||||||
|
for (i = 0; i < brw->vb.nr_vb; i++) {
|
||||||
|
OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) |
|
||||||
|
BRW_VB0_ACCESS_VERTEXDATA |
|
||||||
|
(brw->vb.vb[i].stride << BRW_VB0_PITCH_SHIFT));
|
||||||
|
OUT_RELOC(brw->vb.vb[i].bo,
|
||||||
|
I915_GEM_DOMAIN_VERTEX, 0,
|
||||||
|
brw->vb.vb[i].offset);
|
||||||
|
if (BRW_IS_IGDNG(brw)) {
|
||||||
|
OUT_RELOC(brw->vb.vb[i].bo,
|
||||||
|
I915_GEM_DOMAIN_VERTEX, 0,
|
||||||
|
brw->vb.vb[i].bo->size - 1);
|
||||||
|
} else
|
||||||
|
OUT_BATCH(brw->vb.vb[i].stride ? brw->vb.vb[i].vertex_count : 0);
|
||||||
|
OUT_BATCH(0); /* Instance data step rate */
|
||||||
|
}
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int brw_emit_vertex_elements(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
|
@ -262,7 +330,7 @@ static void brw_emit_vertices(struct brw_context *brw)
|
||||||
* The stale VB state stays in place, but they don't do anything unless
|
* The stale VB state stays in place, but they don't do anything unless
|
||||||
* a VE loads from them.
|
* a VE loads from them.
|
||||||
*/
|
*/
|
||||||
if (brw->vb.nr_enabled == 0) {
|
if (brw->vb.nr_ve == 0) {
|
||||||
BEGIN_BATCH(3, IGNORE_CLIPRECTS);
|
BEGIN_BATCH(3, IGNORE_CLIPRECTS);
|
||||||
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
|
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
|
||||||
OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
|
OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
|
||||||
|
@ -274,59 +342,23 @@ static void brw_emit_vertices(struct brw_context *brw)
|
||||||
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
|
(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
|
||||||
(BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
|
(BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now emit VB and VEP state packets.
|
/* Now emit vertex element (VEP) state packets.
|
||||||
*
|
*
|
||||||
* This still defines a hardware VB for each input, even if they
|
|
||||||
* are interleaved or from the same VBO. TBD if this makes a
|
|
||||||
* performance difference.
|
|
||||||
*/
|
*/
|
||||||
BEGIN_BATCH(1 + brw->vb.nr_enabled * 4, IGNORE_CLIPRECTS);
|
BEGIN_BATCH(1 + brw->curr.num_vertex_elements * 2, IGNORE_CLIPRECTS);
|
||||||
OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
|
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_ve * 2) - 2));
|
||||||
((1 + brw->vb.nr_enabled * 4) - 2));
|
for (i = 0; i < brw->vb.nr_ve; i++) {
|
||||||
|
const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
|
||||||
for (i = 0; i < brw->vb.nr_enabled; i++) {
|
uint32_t format = brw_translate_surface_format( input->src_format );
|
||||||
struct brw_vertex_element *input = brw->vb.enabled[i];
|
|
||||||
|
|
||||||
OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) |
|
|
||||||
BRW_VB0_ACCESS_VERTEXDATA |
|
|
||||||
(input->stride << BRW_VB0_PITCH_SHIFT));
|
|
||||||
OUT_RELOC(input->bo,
|
|
||||||
I915_GEM_DOMAIN_VERTEX, 0,
|
|
||||||
input->offset);
|
|
||||||
if (BRW_IS_IGDNG(brw)) {
|
|
||||||
if (input->stride) {
|
|
||||||
OUT_RELOC(input->bo,
|
|
||||||
I915_GEM_DOMAIN_VERTEX, 0,
|
|
||||||
input->offset + input->stride * input->count - 1);
|
|
||||||
} else {
|
|
||||||
assert(input->count == 1);
|
|
||||||
OUT_RELOC(input->bo,
|
|
||||||
I915_GEM_DOMAIN_VERTEX, 0,
|
|
||||||
input->offset + input->element_size - 1);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
OUT_BATCH(input->stride ? input->count : 0);
|
|
||||||
OUT_BATCH(0); /* Instance data step rate */
|
|
||||||
}
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
|
|
||||||
BEGIN_BATCH(1 + brw->vb.nr_enabled * 2, IGNORE_CLIPRECTS);
|
|
||||||
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2));
|
|
||||||
for (i = 0; i < brw->vb.nr_enabled; i++) {
|
|
||||||
struct brw_vertex_element *input = brw->vb.enabled[i];
|
|
||||||
uint32_t format = get_surface_type(input->glarray->Type,
|
|
||||||
input->glarray->Size,
|
|
||||||
input->glarray->Format,
|
|
||||||
input->glarray->Normalized);
|
|
||||||
uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
|
uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
|
||||||
uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
|
uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
|
||||||
uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
|
uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
|
||||||
uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
|
uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
|
||||||
|
|
||||||
switch (input->glarray->Size) {
|
switch (input->nr_components) {
|
||||||
case 0: comp0 = BRW_VE1_COMPONENT_STORE_0;
|
case 0: comp0 = BRW_VE1_COMPONENT_STORE_0;
|
||||||
case 1: comp1 = BRW_VE1_COMPONENT_STORE_0;
|
case 1: comp1 = BRW_VE1_COMPONENT_STORE_0;
|
||||||
case 2: comp2 = BRW_VE1_COMPONENT_STORE_0;
|
case 2: comp2 = BRW_VE1_COMPONENT_STORE_0;
|
||||||
|
@ -352,11 +384,29 @@ static void brw_emit_vertices(struct brw_context *brw)
|
||||||
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
|
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
|
||||||
}
|
}
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int brw_emit_vertices( struct brw_context *brw )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = brw_emit_vertex_buffers( brw );
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = brw_emit_vertex_elements( brw );
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct brw_tracked_state brw_vertices = {
|
const struct brw_tracked_state brw_vertices = {
|
||||||
.dirty = {
|
.dirty = {
|
||||||
.mesa = 0,
|
.mesa = PIPE_NEW_INDEX_RANGE,
|
||||||
.brw = BRW_NEW_BATCH | BRW_NEW_VERTICES,
|
.brw = BRW_NEW_BATCH | BRW_NEW_VERTICES,
|
||||||
.cache = 0,
|
.cache = 0,
|
||||||
},
|
},
|
||||||
|
@ -364,104 +414,106 @@ const struct brw_tracked_state brw_vertices = {
|
||||||
.emit = brw_emit_vertices,
|
.emit = brw_emit_vertices,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void brw_prepare_indices(struct brw_context *brw)
|
|
||||||
|
static int brw_prepare_indices(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
const struct _mesa_index_buffer *index_buffer = brw->ib.ib;
|
struct pipe_buffer *index_buffer = brw->curr.index_buffer;
|
||||||
GLuint ib_size;
|
|
||||||
struct brw_winsys_buffer *bo = NULL;
|
struct brw_winsys_buffer *bo = NULL;
|
||||||
struct gl_buffer_object *bufferobj;
|
|
||||||
GLuint offset;
|
GLuint offset;
|
||||||
GLuint ib_type_size;
|
GLuint index_size;
|
||||||
|
GLuint ib_size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (index_buffer == NULL)
|
if (index_buffer == NULL)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
ib_type_size = get_size(index_buffer->type);
|
if (DEBUG & DEBUG_VERTS)
|
||||||
ib_size = ib_type_size * index_buffer->count;
|
debug_printf("%s: index_size:%d index_buffer->size:%d\n",
|
||||||
bufferobj = index_buffer->obj;;
|
__FUNCTION__,
|
||||||
|
brw->curr.index_size,
|
||||||
|
brw->curr.index_buffer->size);
|
||||||
|
|
||||||
/* Turn into a proper VBO:
|
ib_size = index_buffer->size;
|
||||||
|
index_size = brw->curr.index_size;
|
||||||
|
|
||||||
|
/* Turn userbuffer into a proper hardware buffer?
|
||||||
*/
|
*/
|
||||||
if (!_mesa_is_bufferobj(bufferobj)) {
|
if (brw_buffer_is_user_buffer(index_buffer)) {
|
||||||
brw->ib.start_vertex_offset = 0;
|
struct pipe_buffer *upload_buf;
|
||||||
|
|
||||||
/* Get new bufferobj, offset:
|
ret = u_upload_buffer( brw->vb.upload_index,
|
||||||
|
0,
|
||||||
|
ib_size,
|
||||||
|
index_buffer,
|
||||||
|
&offset,
|
||||||
|
&upload_buf );
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bo = brw_buffer(upload_buf)->bo;
|
||||||
|
brw->sws->bo_reference(bo);
|
||||||
|
pipe_buffer_reference( &upload_buf, NULL );
|
||||||
|
|
||||||
|
/* XXX: annotate the userbuffer with the upload information so
|
||||||
|
* that successive calls don't get re-uploaded.
|
||||||
*/
|
*/
|
||||||
get_space(brw, ib_size, &bo, &offset);
|
}
|
||||||
|
else {
|
||||||
/* Straight upload
|
bo = brw_buffer(index_buffer)->bo;
|
||||||
*/
|
|
||||||
brw_bo_subdata(bo, offset, ib_size, index_buffer->ptr);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
offset = (GLuint) (unsigned long) index_buffer->ptr;
|
|
||||||
brw->ib.start_vertex_offset = 0;
|
|
||||||
|
|
||||||
/* If the index buffer isn't aligned to its element size, we have to
|
|
||||||
* rebase it into a temporary.
|
|
||||||
*/
|
|
||||||
if ((get_size(index_buffer->type) - 1) & offset) {
|
|
||||||
GLubyte *map = ctx->Driver.MapBuffer(ctx,
|
|
||||||
GL_ELEMENT_ARRAY_BUFFER_ARB,
|
|
||||||
GL_DYNAMIC_DRAW_ARB,
|
|
||||||
bufferobj);
|
|
||||||
map += offset;
|
|
||||||
|
|
||||||
get_space(brw, ib_size, &bo, &offset);
|
|
||||||
|
|
||||||
dri_bo_subdata(bo, offset, ib_size, map);
|
|
||||||
|
|
||||||
ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj);
|
|
||||||
} else {
|
|
||||||
bo = intel_bufferobj_buffer(intel, intel_buffer_object(bufferobj),
|
|
||||||
INTEL_READ);
|
|
||||||
brw->sws->bo_reference(bo);
|
brw->sws->bo_reference(bo);
|
||||||
|
|
||||||
/* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading
|
|
||||||
* the index buffer state when we're just moving the start index
|
|
||||||
* of our drawing.
|
|
||||||
*/
|
|
||||||
brw->ib.start_vertex_offset = offset / ib_type_size;
|
|
||||||
offset = 0;
|
|
||||||
ib_size = bo->size;
|
ib_size = bo->size;
|
||||||
}
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the
|
||||||
|
* index buffer state when we're just moving the start index of our
|
||||||
|
* drawing.
|
||||||
|
*
|
||||||
|
* In gallium this will happen in the case where successive draw
|
||||||
|
* calls are made with (distinct?) userbuffers, but the upload_mgr
|
||||||
|
* places the data into a single winsys buffer.
|
||||||
|
*
|
||||||
|
* This statechange doesn't raise any state flags and is always
|
||||||
|
* just merged into the final draw packet:
|
||||||
|
*/
|
||||||
|
if (1) {
|
||||||
|
assert((offset & (index_size - 1)) == 0);
|
||||||
|
brw->ib.start_vertex_offset = offset / index_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These statechanges trigger a new CMD_INDEX_BUFFER packet:
|
||||||
|
*/
|
||||||
if (brw->ib.bo != bo ||
|
if (brw->ib.bo != bo ||
|
||||||
brw->ib.offset != offset ||
|
|
||||||
brw->ib.size != ib_size)
|
brw->ib.size != ib_size)
|
||||||
{
|
{
|
||||||
drm_intel_bo_unreference(brw->ib.bo);
|
brw->sws->bo_unreference(brw->ib.bo);
|
||||||
brw->ib.bo = bo;
|
brw->ib.bo = bo;
|
||||||
brw->ib.offset = offset;
|
|
||||||
brw->ib.size = ib_size;
|
brw->ib.size = ib_size;
|
||||||
|
|
||||||
brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
|
brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
|
||||||
} else {
|
}
|
||||||
drm_intel_bo_unreference(bo);
|
else {
|
||||||
|
brw->sws->bo_unreference(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
brw_add_validated_bo(brw, brw->ib.bo);
|
brw_add_validated_bo(brw, brw->ib.bo);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_indices = {
|
const struct brw_tracked_state brw_indices = {
|
||||||
.dirty = {
|
.dirty = {
|
||||||
.mesa = 0,
|
.mesa = PIPE_NEW_INDEX_BUFFER,
|
||||||
.brw = BRW_NEW_INDICES,
|
.brw = 0,
|
||||||
.cache = 0,
|
.cache = 0,
|
||||||
},
|
},
|
||||||
.prepare = brw_prepare_indices,
|
.prepare = brw_prepare_indices,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void brw_emit_index_buffer(struct brw_context *brw)
|
static int brw_emit_index_buffer(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
const struct _mesa_index_buffer *index_buffer = brw->ib.ib;
|
|
||||||
|
|
||||||
if (index_buffer == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Emit the indexbuffer packet:
|
/* Emit the indexbuffer packet:
|
||||||
*/
|
*/
|
||||||
|
if (brw->ib.bo)
|
||||||
{
|
{
|
||||||
struct brw_indexbuffer ib;
|
struct brw_indexbuffer ib;
|
||||||
|
|
||||||
|
@ -469,7 +521,7 @@ static void brw_emit_index_buffer(struct brw_context *brw)
|
||||||
|
|
||||||
ib.header.bits.opcode = CMD_INDEX_BUFFER;
|
ib.header.bits.opcode = CMD_INDEX_BUFFER;
|
||||||
ib.header.bits.length = sizeof(ib)/4 - 2;
|
ib.header.bits.length = sizeof(ib)/4 - 2;
|
||||||
ib.header.bits.index_format = get_index_type(index_buffer->type);
|
ib.header.bits.index_format = get_index_type(brw->ib.size);
|
||||||
ib.header.bits.cut_index_enable = 0;
|
ib.header.bits.cut_index_enable = 0;
|
||||||
|
|
||||||
BEGIN_BATCH(4, IGNORE_CLIPRECTS);
|
BEGIN_BATCH(4, IGNORE_CLIPRECTS);
|
||||||
|
@ -483,6 +535,8 @@ static void brw_emit_index_buffer(struct brw_context *brw)
|
||||||
OUT_BATCH( 0 );
|
OUT_BATCH( 0 );
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct brw_tracked_state brw_index_buffer = {
|
const struct brw_tracked_state brw_index_buffer = {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
* Keith Whitwell <keith@tungstengraphics.com>
|
* Keith Whitwell <keith@tungstengraphics.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "util/u_memory.h"
|
||||||
|
|
||||||
#include "brw_context.h"
|
#include "brw_context.h"
|
||||||
#include "brw_defines.h"
|
#include "brw_defines.h"
|
||||||
|
@ -237,7 +238,7 @@ brw_resolve_cals(struct brw_compile *c)
|
||||||
struct brw_glsl_call *call, *next;
|
struct brw_glsl_call *call, *next;
|
||||||
for (call = c->first_call; call; call = next) {
|
for (call = c->first_call; call; call = next) {
|
||||||
next = call->next;
|
next = call->next;
|
||||||
_mesa_free(call);
|
FREE(call);
|
||||||
}
|
}
|
||||||
c->first_call = NULL;
|
c->first_call = NULL;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ brw_resolve_cals(struct brw_compile *c)
|
||||||
struct brw_glsl_label *label, *next;
|
struct brw_glsl_label *label, *next;
|
||||||
for (label = c->first_label; label; label = next) {
|
for (label = c->first_label; label; label = next) {
|
||||||
next = label->next;
|
next = label->next;
|
||||||
_mesa_free(label);
|
FREE(label);
|
||||||
}
|
}
|
||||||
c->first_label = NULL;
|
c->first_label = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
* Keith Whitwell <keith@tungstengraphics.com>
|
* Keith Whitwell <keith@tungstengraphics.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "util/u_debug.h"
|
||||||
|
|
||||||
#include "brw_eu.h"
|
#include "brw_eu.h"
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ void brw_print_reg( struct brw_reg hwreg )
|
||||||
"f"
|
"f"
|
||||||
};
|
};
|
||||||
|
|
||||||
_mesa_printf("%s%s",
|
debug_printf("%s%s",
|
||||||
hwreg.abs ? "abs/" : "",
|
hwreg.abs ? "abs/" : "",
|
||||||
hwreg.negate ? "-" : "");
|
hwreg.negate ? "-" : "");
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ void brw_print_reg( struct brw_reg hwreg )
|
||||||
hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 &&
|
hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 &&
|
||||||
hwreg.type == BRW_REGISTER_TYPE_F) {
|
hwreg.type == BRW_REGISTER_TYPE_F) {
|
||||||
/* vector register */
|
/* vector register */
|
||||||
_mesa_printf("vec%d", hwreg.nr);
|
debug_printf("vec%d", hwreg.nr);
|
||||||
}
|
}
|
||||||
else if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
|
else if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
|
||||||
hwreg.vstride == BRW_VERTICAL_STRIDE_0 &&
|
hwreg.vstride == BRW_VERTICAL_STRIDE_0 &&
|
||||||
|
@ -72,13 +73,13 @@ void brw_print_reg( struct brw_reg hwreg )
|
||||||
hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 &&
|
hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 &&
|
||||||
hwreg.type == BRW_REGISTER_TYPE_F) {
|
hwreg.type == BRW_REGISTER_TYPE_F) {
|
||||||
/* "scalar" register */
|
/* "scalar" register */
|
||||||
_mesa_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4);
|
debug_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4);
|
||||||
}
|
}
|
||||||
else if (hwreg.file == BRW_IMMEDIATE_VALUE) {
|
else if (hwreg.file == BRW_IMMEDIATE_VALUE) {
|
||||||
_mesa_printf("imm %f", hwreg.dw1.f);
|
debug_printf("imm %f", hwreg.dw1.f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mesa_printf("%s%d.%d<%d;%d,%d>:%s",
|
debug_printf("%s%d.%d<%d;%d,%d>:%s",
|
||||||
file[hwreg.file],
|
file[hwreg.file],
|
||||||
hwreg.nr,
|
hwreg.nr,
|
||||||
hwreg.subnr / type_sz(hwreg.type),
|
hwreg.subnr / type_sz(hwreg.type),
|
||||||
|
|
|
@ -315,24 +315,20 @@ const struct brw_tracked_state brw_polygon_stipple = {
|
||||||
|
|
||||||
static void upload_polygon_stipple_offset(struct brw_context *brw)
|
static void upload_polygon_stipple_offset(struct brw_context *brw)
|
||||||
{
|
{
|
||||||
__DRIdrawablePrivate *dPriv = brw->intel.driDrawable;
|
|
||||||
struct brw_polygon_stipple_offset bpso;
|
struct brw_polygon_stipple_offset bpso;
|
||||||
|
|
||||||
memset(&bpso, 0, sizeof(bpso));
|
memset(&bpso, 0, sizeof(bpso));
|
||||||
bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
|
bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
|
||||||
bpso.header.length = sizeof(bpso)/4-2;
|
bpso.header.length = sizeof(bpso)/4-2;
|
||||||
|
|
||||||
/* If we're drawing to a system window (ctx->DrawBuffer->Name == 0),
|
/* Never need to offset stipple coordinates.
|
||||||
* we have to invert the Y axis in order to match the OpenGL
|
*
|
||||||
* pixel coordinate system, and our offset must be matched
|
* XXX: is it ever necessary to invert Y values?
|
||||||
* to the window position. If we're drawing to a FBO
|
|
||||||
* (ctx->DrawBuffer->Name != 0), then our native pixel coordinate
|
|
||||||
* system works just fine, and there's no window system to
|
|
||||||
* worry about.
|
|
||||||
*/
|
*/
|
||||||
if (brw->intel.ctx.DrawBuffer->Name == 0) {
|
if (0) {
|
||||||
bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31;
|
int x = 0, y = 0, h = 0;
|
||||||
bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31;
|
bpso.bits0.x_offset = (32 - (x & 31)) & 31;
|
||||||
|
bpso.bits0.y_offset = (32 - ((y + h) & 31)) & 31;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bpso.bits0.y_offset = 0;
|
bpso.bits0.y_offset = 0;
|
||||||
|
|
|
@ -53,6 +53,9 @@ static void brw_note_fence( struct brw_context *brw, GLuint fence )
|
||||||
static GLuint brw_flush_cmd( void )
|
static GLuint brw_flush_cmd( void )
|
||||||
{
|
{
|
||||||
struct brw_mi_flush flush;
|
struct brw_mi_flush flush;
|
||||||
|
|
||||||
|
return ;
|
||||||
|
|
||||||
flush.opcode = CMD_MI_FLUSH;
|
flush.opcode = CMD_MI_FLUSH;
|
||||||
flush.pad = 0;
|
flush.pad = 0;
|
||||||
flush.flags = BRW_FLUSH_STATE_CACHE;
|
flush.flags = BRW_FLUSH_STATE_CACHE;
|
||||||
|
|
|
@ -33,6 +33,25 @@
|
||||||
#include "brw_util.h"
|
#include "brw_util.h"
|
||||||
#include "brw_wm.h"
|
#include "brw_wm.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given fragment program uses GLSL features such
|
||||||
|
* as flow conditionals, loops, subroutines.
|
||||||
|
* Some GLSL shaders may use these features, others might not.
|
||||||
|
*/
|
||||||
|
GLboolean brw_wm_is_glsl(const struct brw_fragment_shader *fp)
|
||||||
|
{
|
||||||
|
return (fp->info.insn_count[TGSI_OPCODE_ARL] > 0 ||
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_IF] > 0 ||
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_ENDIF] > 0 || /* redundant - IF */
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_CAL] > 0 ||
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_BRK] > 0 || /* redundant - BGNLOOP */
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_RET] > 0 || /* redundant - CAL */
|
||||||
|
fp->info.insn_count[TGSI_OPCODE_BGNLOOP] > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void brwBindProgram( struct brw_context *brw,
|
static void brwBindProgram( struct brw_context *brw,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
struct gl_program *prog )
|
struct gl_program *prog )
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
|
|
||||||
static void brw_merge_inputs( struct brw_context *brw,
|
|
||||||
const struct gl_client_array *arrays[])
|
|
||||||
|
void
|
||||||
|
brw_pipe_vertex_cleanup( struct brw_context *brw )
|
||||||
{
|
{
|
||||||
struct brw_vertex_info old = brw->vb.info;
|
|
||||||
GLuint i;
|
|
||||||
|
|
||||||
for (i = 0; i < VERT_ATTRIB_MAX; i++)
|
|
||||||
brw->sws->bo_unreference(brw->vb.inputs[i].bo);
|
|
||||||
|
|
||||||
memset(&brw->vb.inputs, 0, sizeof(brw->vb.inputs));
|
|
||||||
memset(&brw->vb.info, 0, sizeof(brw->vb.info));
|
|
||||||
|
|
||||||
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
|
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
|
||||||
brw->vb.inputs[i].glarray = arrays[i];
|
brw->sws->bo_unreference(brw->vb.inputs[i].bo);
|
||||||
brw->vb.inputs[i].attrib = (gl_vert_attrib) i;
|
brw->vb.inputs[i].bo = NULL;
|
||||||
|
|
||||||
if (arrays[i]->StrideB != 0)
|
|
||||||
brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) <<
|
|
||||||
((i%16) * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Raise statechanges if input sizes have changed. */
|
|
||||||
if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0)
|
|
||||||
brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,14 @@ struct brw_transfer
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct brw_buffer
|
||||||
|
{
|
||||||
|
struct pipe_buffer base;
|
||||||
|
struct brw_winsys_buffer *bo;
|
||||||
|
void *ptr;
|
||||||
|
boolean is_user_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cast wrappers
|
* Cast wrappers
|
||||||
|
@ -72,5 +80,19 @@ brw_transfer(struct pipe_transfer *transfer)
|
||||||
return (struct brw_transfer *)transfer;
|
return (struct brw_transfer *)transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE struct brw_buffer *
|
||||||
|
brw_buffer(struct pipe_buffer *buffer)
|
||||||
|
{
|
||||||
|
return (struct brw_buffer *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pipe buffer helpers
|
||||||
|
*/
|
||||||
|
static INLINE boolean
|
||||||
|
brw_buffer_is_user_buffer( const struct pipe_buffer *buf )
|
||||||
|
{
|
||||||
|
return ((const struct brw_buffer *)buf)->is_user_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* BRW_SCREEN_H */
|
#endif /* BRW_SCREEN_H */
|
||||||
|
|
|
@ -134,7 +134,7 @@ static void upload_sf_prog(struct brw_context *brw)
|
||||||
key.attrs = brw->vs.prog_data->outputs_written;
|
key.attrs = brw->vs.prog_data->outputs_written;
|
||||||
|
|
||||||
/* BRW_NEW_REDUCED_PRIMITIVE */
|
/* BRW_NEW_REDUCED_PRIMITIVE */
|
||||||
switch (brw->intel.reduced_primitive) {
|
switch (brw->reduced_primitive) {
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
/* NOTE: We just use the edgeflag attribute as an indicator that
|
/* NOTE: We just use the edgeflag attribute as an indicator that
|
||||||
* unfilled triangles are active. We don't actually do the
|
* unfilled triangles are active. We don't actually do the
|
||||||
|
|
|
@ -40,19 +40,12 @@ static void upload_sf_vp(struct brw_context *brw)
|
||||||
const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
|
const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
|
||||||
struct brw_sf_viewport sfv;
|
struct brw_sf_viewport sfv;
|
||||||
GLfloat y_scale, y_bias;
|
GLfloat y_scale, y_bias;
|
||||||
const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0);
|
|
||||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||||
|
|
||||||
memset(&sfv, 0, sizeof(sfv));
|
memset(&sfv, 0, sizeof(sfv));
|
||||||
|
|
||||||
if (render_to_fbo) {
|
|
||||||
y_scale = 1.0;
|
y_scale = 1.0;
|
||||||
y_bias = 0;
|
y_bias = 0;
|
||||||
}
|
|
||||||
else {
|
|
||||||
y_scale = -1.0;
|
|
||||||
y_bias = ctx->DrawBuffer->Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _NEW_VIEWPORT */
|
/* _NEW_VIEWPORT */
|
||||||
|
|
||||||
|
@ -73,20 +66,11 @@ static void upload_sf_vp(struct brw_context *brw)
|
||||||
* Note that the hardware's coordinates are inclusive, while Mesa's min is
|
* Note that the hardware's coordinates are inclusive, while Mesa's min is
|
||||||
* inclusive but max is exclusive.
|
* inclusive but max is exclusive.
|
||||||
*/
|
*/
|
||||||
if (render_to_fbo) {
|
/* Y=0=bottom */
|
||||||
/* texmemory: Y=0=bottom */
|
|
||||||
sfv.scissor.xmin = ctx->DrawBuffer->_Xmin;
|
sfv.scissor.xmin = ctx->DrawBuffer->_Xmin;
|
||||||
sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
|
sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
|
||||||
sfv.scissor.ymin = ctx->DrawBuffer->_Ymin;
|
sfv.scissor.ymin = ctx->DrawBuffer->_Ymin;
|
||||||
sfv.scissor.ymax = ctx->DrawBuffer->_Ymax - 1;
|
sfv.scissor.ymax = ctx->DrawBuffer->_Ymax - 1;
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* memory: Y=0=top */
|
|
||||||
sfv.scissor.xmin = ctx->DrawBuffer->_Xmin;
|
|
||||||
sfv.scissor.xmax = ctx->DrawBuffer->_Xmax - 1;
|
|
||||||
sfv.scissor.ymin = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax;
|
|
||||||
sfv.scissor.ymax = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
brw->sws->bo_unreference(brw->sf.vp_bo);
|
brw->sws->bo_unreference(brw->sf.vp_bo);
|
||||||
brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 );
|
brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 );
|
||||||
|
@ -151,7 +135,7 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
|
||||||
/* _NEW_LIGHT */
|
/* _NEW_LIGHT */
|
||||||
key->provoking_vertex = ctx->Light.ProvokingVertex;
|
key->provoking_vertex = ctx->Light.ProvokingVertex;
|
||||||
|
|
||||||
key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
|
key->render_to_fbo = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct brw_winsys_buffer *
|
static struct brw_winsys_buffer *
|
||||||
|
@ -211,11 +195,6 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
|
||||||
else
|
else
|
||||||
sf.sf5.front_winding = BRW_FRONTWINDING_CW;
|
sf.sf5.front_winding = BRW_FRONTWINDING_CW;
|
||||||
|
|
||||||
/* The viewport is inverted for rendering to a FBO, and that inverts
|
|
||||||
* polygon front/back orientation.
|
|
||||||
*/
|
|
||||||
sf.sf5.front_winding ^= key->render_to_fbo;
|
|
||||||
|
|
||||||
switch (key->cull_face) {
|
switch (key->cull_face) {
|
||||||
case GL_FRONT:
|
case GL_FRONT:
|
||||||
sf.sf6.cull_mode = BRW_CULLMODE_FRONT;
|
sf.sf6.cull_mode = BRW_CULLMODE_FRONT;
|
||||||
|
@ -245,7 +224,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
|
||||||
sf.sf6.line_width = 0;
|
sf.sf6.line_width = 0;
|
||||||
|
|
||||||
/* _NEW_BUFFERS */
|
/* _NEW_BUFFERS */
|
||||||
key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
|
key->render_to_fbo = 1;
|
||||||
if (!key->render_to_fbo) {
|
if (!key->render_to_fbo) {
|
||||||
/* Rendering to an OpenGL window */
|
/* Rendering to an OpenGL window */
|
||||||
sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
|
sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
|
||||||
|
|
|
@ -109,8 +109,8 @@ struct brw_surface_key {
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* brw_state.c
|
* brw_state.c
|
||||||
*/
|
*/
|
||||||
void brw_validate_state(struct brw_context *brw);
|
int brw_validate_state(struct brw_context *brw);
|
||||||
void brw_upload_state(struct brw_context *brw);
|
int brw_upload_state(struct brw_context *brw);
|
||||||
void brw_init_state(struct brw_context *brw);
|
void brw_init_state(struct brw_context *brw);
|
||||||
void brw_destroy_state(struct brw_context *brw);
|
void brw_destroy_state(struct brw_context *brw);
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ void brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* brw_state_batch.c
|
* brw_state_batch.c
|
||||||
*/
|
*/
|
||||||
#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->intel.batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS)
|
#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS)
|
||||||
#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
|
#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
|
||||||
|
|
||||||
GLboolean brw_cached_batch_struct( struct brw_context *brw,
|
GLboolean brw_cached_batch_struct( struct brw_context *brw,
|
||||||
|
|
|
@ -47,7 +47,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
|
||||||
struct header *newheader = (struct header *)data;
|
struct header *newheader = (struct header *)data;
|
||||||
|
|
||||||
if (brw->emit_state_always) {
|
if (brw->emit_state_always) {
|
||||||
brw_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS);
|
brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
|
||||||
|
|
||||||
emit:
|
emit:
|
||||||
memcpy(item->header, newheader, sz);
|
memcpy(item->header, newheader, sz);
|
||||||
brw_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS);
|
brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ static GLboolean check_fallbacks( struct brw_context *brw,
|
||||||
* use fallbacks. If we're forcing fallbacks, always
|
* use fallbacks. If we're forcing fallbacks, always
|
||||||
* use fallfacks.
|
* use fallfacks.
|
||||||
*/
|
*/
|
||||||
if (brw->intel.conformance_mode == 0)
|
if (brw->flags.no_swtnl)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
if (brw->intel.conformance_mode == 2)
|
if (brw->flags.force_swtnl)
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
|
|
||||||
if (ctx->Polygon.SmoothFlag) {
|
if (brw->curr.rast->tmpl.smooth_polys) {
|
||||||
for (i = 0; i < nr_prims; i++)
|
for (i = 0; i < nr_prims; i++)
|
||||||
if (reduced_prim[prim[i].mode] == GL_TRIANGLES)
|
if (reduced_prim[prim[i].mode] == GL_TRIANGLES)
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
|
|
|
@ -161,6 +161,13 @@ struct brw_winsys_screen {
|
||||||
size_t size,
|
size_t size,
|
||||||
const void *data);
|
const void *data);
|
||||||
|
|
||||||
|
/* XXX: couldn't this be handled by returning true/false on
|
||||||
|
* bo_emit_reloc?
|
||||||
|
*/
|
||||||
|
boolean (*check_aperture_space)( struct brw_winsys_screen *iws,
|
||||||
|
struct brw_winsys_buffer **buffers,
|
||||||
|
unsigned count );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a buffer.
|
* Map a buffer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -158,7 +158,7 @@ static void do_wm_prog( struct brw_context *brw,
|
||||||
memcpy(&c->key, key, sizeof(*key));
|
memcpy(&c->key, key, sizeof(*key));
|
||||||
|
|
||||||
c->fp = fp;
|
c->fp = fp;
|
||||||
c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
|
c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/
|
||||||
|
|
||||||
brw_init_compile(brw, &c->func);
|
brw_init_compile(brw, &c->func);
|
||||||
|
|
||||||
|
|
|
@ -131,9 +131,9 @@ struct brw_wm_ref {
|
||||||
GLuint insn:24;
|
GLuint insn:24;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct brw_wm_constref {
|
struct brw_wm_imm_ref {
|
||||||
const struct brw_wm_ref *ref;
|
const struct brw_wm_ref *ref;
|
||||||
GLfloat constval;
|
GLfloat imm1f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,8 +232,8 @@ struct brw_wm_compile {
|
||||||
struct brw_wm_instruction instruction[BRW_WM_MAX_INSN];
|
struct brw_wm_instruction instruction[BRW_WM_MAX_INSN];
|
||||||
GLuint nr_insns;
|
GLuint nr_insns;
|
||||||
|
|
||||||
struct brw_wm_constref constref[BRW_WM_MAX_CONST];
|
struct brw_wm_imm_ref imm_ref[BRW_WM_MAX_CONST];
|
||||||
GLuint nr_constrefs;
|
GLuint nr_imm_refs;
|
||||||
|
|
||||||
struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2];
|
struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2];
|
||||||
|
|
||||||
|
|
|
@ -7,34 +7,6 @@ static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
|
||||||
const struct prog_instruction *inst,
|
const struct prog_instruction *inst,
|
||||||
GLuint component);
|
GLuint component);
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the given fragment program uses GLSL features such
|
|
||||||
* as flow conditionals, loops, subroutines.
|
|
||||||
* Some GLSL shaders may use these features, others might not.
|
|
||||||
*/
|
|
||||||
GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < fp->Base.NumInstructions; i++) {
|
|
||||||
const struct prog_instruction *inst = &fp->Base.Instructions[i];
|
|
||||||
switch (inst->Opcode) {
|
|
||||||
case OPCODE_ARL:
|
|
||||||
case OPCODE_IF:
|
|
||||||
case OPCODE_ENDIF:
|
|
||||||
case OPCODE_CAL:
|
|
||||||
case OPCODE_BRK:
|
|
||||||
case OPCODE_RET:
|
|
||||||
case OPCODE_BGNLOOP:
|
|
||||||
return GL_TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reclaim_temps(struct brw_wm_compile *c);
|
reclaim_temps(struct brw_wm_compile *c);
|
||||||
|
|
|
@ -124,33 +124,33 @@ static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Return a ref to a constant/literal value */
|
/** Return a ref to an immediate value */
|
||||||
static const struct brw_wm_ref *get_const_ref( struct brw_wm_compile *c,
|
static const struct brw_wm_ref *get_imm_ref( struct brw_wm_compile *c,
|
||||||
const GLfloat *constval )
|
const GLfloat *imm1f )
|
||||||
{
|
{
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
/* Search for an existing const value matching the request:
|
/* Search for an existing const value matching the request:
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < c->nr_constrefs; i++) {
|
for (i = 0; i < c->nr_imm_refs; i++) {
|
||||||
if (c->constref[i].constval == *constval)
|
if (c->imm_ref[i].imm_val == *imm1f)
|
||||||
return c->constref[i].ref;
|
return c->imm_ref[i].ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Else try to add a new one:
|
/* Else try to add a new one:
|
||||||
*/
|
*/
|
||||||
if (c->nr_constrefs < BRW_WM_MAX_CONST) {
|
if (c->nr_imm_refs < BRW_WM_MAX_IMM) {
|
||||||
GLuint i = c->nr_constrefs++;
|
GLuint i = c->nr_imm_refs++;
|
||||||
|
|
||||||
/* A constant is a special type of parameter:
|
/* An immediate is a special type of parameter:
|
||||||
*/
|
*/
|
||||||
c->constref[i].constval = *constval;
|
c->imm_ref[i].imm_val = *imm_val;
|
||||||
c->constref[i].ref = get_param_ref(c, constval);
|
c->imm_ref[i].ref = get_param_ref(c, imm_val);
|
||||||
|
|
||||||
return c->constref[i].ref;
|
return c->imm_ref[i].ref;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mesa_printf("%s: out of constrefs\n", __FUNCTION__);
|
_mesa_printf("%s: out of imm_refs\n", __FUNCTION__);
|
||||||
c->prog_data.error = 1;
|
c->prog_data.error = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
|
||||||
case PROGRAM_CONSTANT:
|
case PROGRAM_CONSTANT:
|
||||||
/* These are invarient:
|
/* These are invarient:
|
||||||
*/
|
*/
|
||||||
ref = get_const_ref(c, &plist->ParameterValues[idx][component]);
|
ref = get_imm_ref(c, &plist->ParameterValues[idx][component]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROGRAM_STATE_VAR:
|
case PROGRAM_STATE_VAR:
|
||||||
|
@ -266,9 +266,9 @@ static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
|
||||||
static const GLfloat const_one = 1.0;
|
static const GLfloat const_one = 1.0;
|
||||||
|
|
||||||
if (component == SWIZZLE_ZERO)
|
if (component == SWIZZLE_ZERO)
|
||||||
src_ref = get_const_ref(c, &const_zero);
|
src_ref = get_imm_ref(c, &const_zero);
|
||||||
else if (component == SWIZZLE_ONE)
|
else if (component == SWIZZLE_ONE)
|
||||||
src_ref = get_const_ref(c, &const_one);
|
src_ref = get_imm_ref(c, &const_one);
|
||||||
else
|
else
|
||||||
src_ref = pass0_get_reg(c, src.File, src.Index, component);
|
src_ref = pass0_get_reg(c, src.File, src.Index, component);
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,7 @@ st_draw_vbo(GLcontext *ctx,
|
||||||
|
|
||||||
/* Gallium probably doesn't want this in some cases. */
|
/* Gallium probably doesn't want this in some cases. */
|
||||||
if (!index_bounds_valid)
|
if (!index_bounds_valid)
|
||||||
|
if (!vbo_all_varyings_in_vbos(arrays))
|
||||||
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
||||||
|
|
||||||
/* sanity check for pointer arithmetic below */
|
/* sanity check for pointer arithmetic below */
|
||||||
|
|
Loading…
Reference in New Issue