i965g: wip
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
void brw_buffer_subdata()
|
||||
{
|
||||
if (intel->intelScreen->kernel_exec_fencing) {
|
||||
drm_intel_gem_bo_map_gtt(bo);
|
||||
memcpy((char *)bo->virtual + offset, index_buffer->ptr, ib_size);
|
||||
drm_intel_gem_bo_unmap_gtt(bo);
|
||||
} else {
|
||||
dri_bo_subdata(bo, offset, ib_size, index_buffer->ptr);
|
||||
}
|
||||
}
|
||||
@@ -62,84 +62,21 @@ const struct brw_tracked_state brw_cc_vp = {
|
||||
};
|
||||
|
||||
struct brw_cc_unit_key {
|
||||
GLboolean stencil, stencil_two_side, color_blend, alpha_enabled;
|
||||
|
||||
GLenum stencil_func[2], stencil_fail_op[2];
|
||||
GLenum stencil_pass_depth_fail_op[2], stencil_pass_depth_pass_op[2];
|
||||
GLubyte stencil_ref[2], stencil_write_mask[2], stencil_test_mask[2];
|
||||
GLenum logic_op;
|
||||
|
||||
GLenum blend_eq_rgb, blend_eq_a;
|
||||
GLenum blend_src_rgb, blend_src_a;
|
||||
GLenum blend_dst_rgb, blend_dst_a;
|
||||
|
||||
GLenum alpha_func;
|
||||
GLclampf alpha_ref;
|
||||
|
||||
GLboolean dither;
|
||||
|
||||
GLboolean depth_test, depth_write;
|
||||
GLenum depth_func;
|
||||
struct pipe_depth_stencil_alpha_state dsa;
|
||||
struct pipe_blend_state blend; /* no color mask */
|
||||
};
|
||||
|
||||
static void
|
||||
cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
const unsigned back = ctx->Stencil._BackFace;
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
key->dsa = brw->curr.dsa.base;
|
||||
key->blend = brw->curr.blend.base;
|
||||
|
||||
key->stencil = ctx->Stencil._Enabled;
|
||||
key->stencil_two_side = ctx->Stencil._TestTwoSide;
|
||||
|
||||
if (key->stencil) {
|
||||
key->stencil_func[0] = ctx->Stencil.Function[0];
|
||||
key->stencil_fail_op[0] = ctx->Stencil.FailFunc[0];
|
||||
key->stencil_pass_depth_fail_op[0] = ctx->Stencil.ZFailFunc[0];
|
||||
key->stencil_pass_depth_pass_op[0] = ctx->Stencil.ZPassFunc[0];
|
||||
key->stencil_ref[0] = ctx->Stencil.Ref[0];
|
||||
key->stencil_write_mask[0] = ctx->Stencil.WriteMask[0];
|
||||
key->stencil_test_mask[0] = ctx->Stencil.ValueMask[0];
|
||||
}
|
||||
if (key->stencil_two_side) {
|
||||
key->stencil_func[1] = ctx->Stencil.Function[back];
|
||||
key->stencil_fail_op[1] = ctx->Stencil.FailFunc[back];
|
||||
key->stencil_pass_depth_fail_op[1] = ctx->Stencil.ZFailFunc[back];
|
||||
key->stencil_pass_depth_pass_op[1] = ctx->Stencil.ZPassFunc[back];
|
||||
key->stencil_ref[1] = ctx->Stencil.Ref[back];
|
||||
key->stencil_write_mask[1] = ctx->Stencil.WriteMask[back];
|
||||
key->stencil_test_mask[1] = ctx->Stencil.ValueMask[back];
|
||||
}
|
||||
|
||||
if (ctx->Color._LogicOpEnabled)
|
||||
key->logic_op = ctx->Color.LogicOp;
|
||||
else
|
||||
key->logic_op = GL_COPY;
|
||||
|
||||
key->color_blend = ctx->Color.BlendEnabled;
|
||||
if (key->color_blend) {
|
||||
key->blend_eq_rgb = ctx->Color.BlendEquationRGB;
|
||||
key->blend_eq_a = ctx->Color.BlendEquationA;
|
||||
key->blend_src_rgb = ctx->Color.BlendSrcRGB;
|
||||
key->blend_dst_rgb = ctx->Color.BlendDstRGB;
|
||||
key->blend_src_a = ctx->Color.BlendSrcA;
|
||||
key->blend_dst_a = ctx->Color.BlendDstA;
|
||||
}
|
||||
|
||||
key->alpha_enabled = ctx->Color.AlphaEnabled;
|
||||
if (key->alpha_enabled) {
|
||||
key->alpha_func = ctx->Color.AlphaFunc;
|
||||
key->alpha_ref = ctx->Color.AlphaRef;
|
||||
}
|
||||
|
||||
key->dither = ctx->Color.DitherFlag;
|
||||
|
||||
key->depth_test = ctx->Depth.Test;
|
||||
if (key->depth_test) {
|
||||
key->depth_func = ctx->Depth.Func;
|
||||
key->depth_write = ctx->Depth.Mask;
|
||||
}
|
||||
/* Clear non-respected values:
|
||||
*/
|
||||
key->blend.colormask = 0xf;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,103 +90,16 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key)
|
||||
|
||||
memset(&cc, 0, sizeof(cc));
|
||||
|
||||
/* _NEW_STENCIL */
|
||||
if (key->stencil) {
|
||||
cc.cc0.stencil_enable = 1;
|
||||
cc.cc0.stencil_func =
|
||||
intel_translate_compare_func(key->stencil_func[0]);
|
||||
cc.cc0.stencil_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_fail_op[0]);
|
||||
cc.cc0.stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[0]);
|
||||
cc.cc0.stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[0]);
|
||||
cc.cc1.stencil_ref = key->stencil_ref[0];
|
||||
cc.cc1.stencil_write_mask = key->stencil_write_mask[0];
|
||||
cc.cc1.stencil_test_mask = key->stencil_test_mask[0];
|
||||
|
||||
if (key->stencil_two_side) {
|
||||
cc.cc0.bf_stencil_enable = 1;
|
||||
cc.cc0.bf_stencil_func =
|
||||
intel_translate_compare_func(key->stencil_func[1]);
|
||||
cc.cc0.bf_stencil_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_fail_op[1]);
|
||||
cc.cc0.bf_stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[1]);
|
||||
cc.cc0.bf_stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[1]);
|
||||
cc.cc1.bf_stencil_ref = key->stencil_ref[1];
|
||||
cc.cc2.bf_stencil_write_mask = key->stencil_write_mask[1];
|
||||
cc.cc2.bf_stencil_test_mask = key->stencil_test_mask[1];
|
||||
}
|
||||
|
||||
/* Not really sure about this:
|
||||
*/
|
||||
if (key->stencil_write_mask[0] ||
|
||||
(key->stencil_two_side && key->stencil_write_mask[1]))
|
||||
cc.cc0.stencil_write_enable = 1;
|
||||
}
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (key->logic_op != GL_COPY) {
|
||||
cc.cc2.logicop_enable = 1;
|
||||
cc.cc5.logicop_func = intel_translate_logic_op(key->logic_op);
|
||||
} else if (key->color_blend) {
|
||||
GLenum eqRGB = key->blend_eq_rgb;
|
||||
GLenum eqA = key->blend_eq_a;
|
||||
GLenum srcRGB = key->blend_src_rgb;
|
||||
GLenum dstRGB = key->blend_dst_rgb;
|
||||
GLenum srcA = key->blend_src_a;
|
||||
GLenum dstA = key->blend_dst_a;
|
||||
|
||||
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
|
||||
srcRGB = dstRGB = GL_ONE;
|
||||
}
|
||||
|
||||
if (eqA == GL_MIN || eqA == GL_MAX) {
|
||||
srcA = dstA = GL_ONE;
|
||||
}
|
||||
|
||||
cc.cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
|
||||
cc.cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
|
||||
cc.cc6.blend_function = brw_translate_blend_equation(eqRGB);
|
||||
|
||||
cc.cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
|
||||
cc.cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
|
||||
cc.cc5.ia_blend_function = brw_translate_blend_equation(eqA);
|
||||
|
||||
cc.cc3.blend_enable = 1;
|
||||
cc.cc3.ia_blend_enable = (srcA != srcRGB ||
|
||||
dstA != dstRGB ||
|
||||
eqA != eqRGB);
|
||||
}
|
||||
|
||||
if (key->alpha_enabled) {
|
||||
cc.cc3.alpha_test = 1;
|
||||
cc.cc3.alpha_test_func = intel_translate_compare_func(key->alpha_func);
|
||||
cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
|
||||
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc.cc7.alpha_ref.ub[0], key->alpha_ref);
|
||||
}
|
||||
|
||||
if (key->dither) {
|
||||
cc.cc5.dither_enable = 1;
|
||||
cc.cc6.y_dither_offset = 0;
|
||||
cc.cc6.x_dither_offset = 0;
|
||||
}
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
if (key->depth_test) {
|
||||
cc.cc2.depth_test = 1;
|
||||
cc.cc2.depth_test_function = intel_translate_compare_func(key->depth_func);
|
||||
cc.cc2.depth_write_enable = key->depth_write;
|
||||
}
|
||||
cc.cc0 = brw->dsa.cc0;
|
||||
cc.cc1 = brw->dsa.cc1;
|
||||
cc.cc2 = brw->dsa.cc2;
|
||||
cc.cc3 = brw->dsa.cc3 | brw->blend.cc3;
|
||||
|
||||
/* CACHE_NEW_CC_VP */
|
||||
cc.cc4.cc_viewport_state_offset = brw->cc.vp_bo->offset >> 5; /* reloc */
|
||||
|
||||
if (INTEL_DEBUG & DEBUG_STATS)
|
||||
cc.cc5.statistics_enable = 1;
|
||||
cc.cc5 = brw->blend.cc5 | brw->debug.cc5;
|
||||
|
||||
|
||||
bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT,
|
||||
key, sizeof(*key),
|
||||
@@ -286,7 +136,7 @@ static void prepare_cc_unit( struct brw_context *brw )
|
||||
|
||||
const struct brw_tracked_state brw_cc_unit = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_STENCIL | _NEW_COLOR | _NEW_DEPTH,
|
||||
.mesa = PIPE_NEW_DEPTH_STENCIL_ALPHA | PIPE_NEW_BLEND,
|
||||
.brw = 0,
|
||||
.cache = CACHE_NEW_CC_VP
|
||||
},
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
@@ -83,7 +83,7 @@ static void compile_clip_prog( struct brw_context *brw,
|
||||
delta += ATTR_SIZE;
|
||||
}
|
||||
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
c.nr_attrs = util_count_bits(c.key.attrs);
|
||||
|
||||
if (BRW_IS_IGDNG(brw))
|
||||
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
|
||||
@@ -104,16 +104,16 @@ static void compile_clip_prog( struct brw_context *brw,
|
||||
* do all three:
|
||||
*/
|
||||
switch (key->primitive) {
|
||||
case GL_TRIANGLES:
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
if (key->do_unfilled)
|
||||
brw_emit_unfilled_clip( &c );
|
||||
else
|
||||
brw_emit_tri_clip( &c );
|
||||
break;
|
||||
case GL_LINES:
|
||||
case PIPE_PRIM_LINES:
|
||||
brw_emit_line_clip( &c );
|
||||
break;
|
||||
case GL_POINTS:
|
||||
case PIPE_PRIM_POINTS:
|
||||
brw_emit_point_clip( &c );
|
||||
break;
|
||||
default:
|
||||
@@ -143,7 +143,6 @@ static void compile_clip_prog( struct brw_context *brw,
|
||||
*/
|
||||
static void upload_clip_prog(struct brw_context *brw)
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
struct brw_clip_prog_key key;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
@@ -151,101 +150,51 @@ static void upload_clip_prog(struct brw_context *brw)
|
||||
/* Populate the key:
|
||||
*/
|
||||
/* BRW_NEW_REDUCED_PRIMITIVE */
|
||||
key.primitive = brw->intel.reduced_primitive;
|
||||
key.primitive = brw->reduced_primitive;
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
key.attrs = brw->vs.prog_data->outputs_written;
|
||||
/* _NEW_LIGHT */
|
||||
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
|
||||
/* _NEW_TRANSFORM */
|
||||
key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
|
||||
/* PIPE_NEW_RAST */
|
||||
key.do_flat_shading = brw->rast.base.flatshade;
|
||||
/* PIPE_NEW_UCP */
|
||||
key.nr_userclip = brw->nr_ucp;
|
||||
|
||||
if (BRW_IS_IGDNG(brw))
|
||||
key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
|
||||
else
|
||||
key.clip_mode = BRW_CLIPMODE_NORMAL;
|
||||
|
||||
/* _NEW_POLYGON */
|
||||
if (key.primitive == GL_TRIANGLES) {
|
||||
if (ctx->Polygon.CullFlag &&
|
||||
ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
|
||||
/* PIPE_NEW_RAST */
|
||||
if (key.primitive == PIPE_PRIM_TRIANGLES) {
|
||||
if (brw->rast->cull_mode = PIPE_WINDING_BOTH)
|
||||
key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
|
||||
else {
|
||||
GLuint fill_front = CLIP_CULL;
|
||||
GLuint fill_back = CLIP_CULL;
|
||||
GLuint offset_front = 0;
|
||||
GLuint offset_back = 0;
|
||||
key.fill_ccw = CLIP_CULL;
|
||||
key.fill_cw = CLIP_CULL;
|
||||
|
||||
if (!ctx->Polygon.CullFlag ||
|
||||
ctx->Polygon.CullFaceMode != GL_FRONT) {
|
||||
switch (ctx->Polygon.FrontMode) {
|
||||
case GL_FILL:
|
||||
fill_front = CLIP_FILL;
|
||||
offset_front = 0;
|
||||
break;
|
||||
case GL_LINE:
|
||||
fill_front = CLIP_LINE;
|
||||
offset_front = ctx->Polygon.OffsetLine;
|
||||
break;
|
||||
case GL_POINT:
|
||||
fill_front = CLIP_POINT;
|
||||
offset_front = ctx->Polygon.OffsetPoint;
|
||||
break;
|
||||
}
|
||||
if (!(brw->rast->cull_mode & PIPE_WINDING_CCW)) {
|
||||
key.fill_ccw = translate_fill(brw->rast.fill_ccw);
|
||||
}
|
||||
|
||||
if (!ctx->Polygon.CullFlag ||
|
||||
ctx->Polygon.CullFaceMode != GL_BACK) {
|
||||
switch (ctx->Polygon.BackMode) {
|
||||
case GL_FILL:
|
||||
fill_back = CLIP_FILL;
|
||||
offset_back = 0;
|
||||
break;
|
||||
case GL_LINE:
|
||||
fill_back = CLIP_LINE;
|
||||
offset_back = ctx->Polygon.OffsetLine;
|
||||
break;
|
||||
case GL_POINT:
|
||||
fill_back = CLIP_POINT;
|
||||
offset_back = ctx->Polygon.OffsetPoint;
|
||||
break;
|
||||
}
|
||||
if (!(brw->rast->cull_mode & PIPE_WINDING_CW)) {
|
||||
key.fill_cw = translate_fill(brw->rast.fill_cw);
|
||||
}
|
||||
|
||||
if (ctx->Polygon.BackMode != GL_FILL ||
|
||||
ctx->Polygon.FrontMode != GL_FILL) {
|
||||
if (key.fill_cw != CLIP_FILL ||
|
||||
key.fill_ccw != CLIP_FILL) {
|
||||
key.do_unfilled = 1;
|
||||
|
||||
/* Most cases the fixed function units will handle. Cases where
|
||||
* one or more polygon faces are unfilled will require help:
|
||||
*/
|
||||
key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
|
||||
}
|
||||
|
||||
if (offset_back || offset_front) {
|
||||
/* _NEW_POLYGON, _NEW_BUFFERS */
|
||||
key.offset_units = ctx->Polygon.OffsetUnits * brw->intel.polygon_offset_scale;
|
||||
key.offset_factor = ctx->Polygon.OffsetFactor * ctx->DrawBuffer->_MRD;
|
||||
}
|
||||
key.offset_ccw = brw->rast.offset_ccw;
|
||||
key.offset_cw = brw->rast.offset_cw;
|
||||
|
||||
switch (ctx->Polygon.FrontFace) {
|
||||
case GL_CCW:
|
||||
key.fill_ccw = fill_front;
|
||||
key.fill_cw = fill_back;
|
||||
key.offset_ccw = offset_front;
|
||||
key.offset_cw = offset_back;
|
||||
if (ctx->Light.Model.TwoSide &&
|
||||
key.fill_cw != CLIP_CULL)
|
||||
key.copy_bfc_cw = 1;
|
||||
break;
|
||||
case GL_CW:
|
||||
key.fill_cw = fill_front;
|
||||
key.fill_ccw = fill_back;
|
||||
key.offset_cw = offset_front;
|
||||
key.offset_ccw = offset_back;
|
||||
if (ctx->Light.Model.TwoSide &&
|
||||
key.fill_ccw != CLIP_CULL)
|
||||
key.copy_bfc_ccw = 1;
|
||||
break;
|
||||
}
|
||||
if (brw->rast.light_twoside &&
|
||||
key.fill_cw != CLIP_CULL)
|
||||
key.copy_bfc_cw = 1;
|
||||
|
||||
if (brw->rast.light_twoside &&
|
||||
key.fill_ccw != CLIP_CULL)
|
||||
key.copy_bfc_ccw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,10 +211,8 @@ static void upload_clip_prog(struct brw_context *brw)
|
||||
|
||||
const struct brw_tracked_state brw_clip_prog = {
|
||||
.dirty = {
|
||||
.mesa = (_NEW_LIGHT |
|
||||
_NEW_TRANSFORM |
|
||||
_NEW_POLYGON |
|
||||
_NEW_BUFFERS),
|
||||
.mesa = (PIPE_NEW_RAST |
|
||||
PIPE_NEW_UCP),
|
||||
.brw = (BRW_NEW_REDUCED_PRIMITIVE),
|
||||
.cache = CACHE_NEW_VS_PROG
|
||||
},
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
*/
|
||||
struct brw_clip_prog_key {
|
||||
GLuint attrs:32;
|
||||
|
||||
GLuint primitive:4;
|
||||
GLuint nr_userclip:3;
|
||||
GLuint do_flat_shading:1;
|
||||
@@ -51,12 +52,10 @@ struct brw_clip_prog_key {
|
||||
GLuint fill_ccw:2; /* includes cull information */
|
||||
GLuint offset_cw:1;
|
||||
GLuint offset_ccw:1;
|
||||
GLuint pad0:17;
|
||||
|
||||
GLuint copy_bfc_cw:1;
|
||||
GLuint copy_bfc_ccw:1;
|
||||
GLuint clip_mode:3;
|
||||
GLuint pad1:27;
|
||||
GLuint pad1:12;
|
||||
|
||||
GLfloat offset_factor;
|
||||
GLfloat offset_units;
|
||||
|
||||
@@ -29,13 +29,6 @@
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
@@ -29,13 +29,6 @@
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_defines.h"
|
||||
#include "main/macros.h"
|
||||
|
||||
struct brw_clip_unit_key {
|
||||
unsigned int total_grf;
|
||||
@@ -66,8 +65,8 @@ clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key)
|
||||
key->nr_urb_entries = brw->urb.nr_clip_entries;
|
||||
key->urb_size = brw->urb.vsize;
|
||||
|
||||
/* _NEW_TRANSOFORM */
|
||||
key->depth_clamp = ctx->Transform.DepthClamp;
|
||||
/* */
|
||||
key->depth_clamp = 0; // XXX: add this to gallium: ctx->Transform.DepthClamp;
|
||||
}
|
||||
|
||||
static dri_bo *
|
||||
@@ -175,7 +174,7 @@ static void upload_clip_unit( struct brw_context *brw )
|
||||
|
||||
const struct brw_tracked_state brw_clip_unit = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_TRANSFORM,
|
||||
.mesa = 0,
|
||||
.brw = (BRW_NEW_CURBE_OFFSETS |
|
||||
BRW_NEW_URB_FENCE),
|
||||
.cache = CACHE_NEW_CLIP_PROG
|
||||
|
||||
@@ -29,13 +29,6 @@
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
@@ -29,11 +29,6 @@
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
|
||||
@@ -30,13 +30,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/program.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
@@ -52,122 +52,77 @@
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/***************************************
|
||||
* Mesa's Driver Functions
|
||||
***************************************/
|
||||
|
||||
static void brwUseProgram(GLcontext *ctx, GLuint program)
|
||||
{
|
||||
_mesa_use_program(ctx, program);
|
||||
}
|
||||
|
||||
static void brwInitProgFuncs( struct dd_function_table *functions )
|
||||
{
|
||||
functions->UseProgram = brwUseProgram;
|
||||
}
|
||||
static void brwInitDriverFunctions( struct dd_function_table *functions )
|
||||
{
|
||||
intelInitDriverFunctions( functions );
|
||||
|
||||
brwInitFragProgFuncs( functions );
|
||||
brwInitProgFuncs( functions );
|
||||
brw_init_queryobj_functions(functions);
|
||||
|
||||
functions->Viewport = intel_viewport;
|
||||
}
|
||||
|
||||
GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
struct dd_function_table functions;
|
||||
struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context);
|
||||
struct intel_context *intel = &brw->intel;
|
||||
GLcontext *ctx = &intel->ctx;
|
||||
|
||||
if (!brw) {
|
||||
_mesa_printf("%s: failed to alloc context\n", __FUNCTION__);
|
||||
debug_printf("%s: failed to alloc context\n", __FUNCTION__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
brwInitVtbl( brw );
|
||||
brwInitDriverFunctions( &functions );
|
||||
|
||||
if (!intelInitContext( intel, mesaVis, driContextPriv,
|
||||
sharedContextPrivate, &functions )) {
|
||||
_mesa_printf("%s: failed to init intel context\n", __FUNCTION__);
|
||||
FREE(brw);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Initialize swrast, tnl driver tables: */
|
||||
intelInitSpanFuncs(ctx);
|
||||
|
||||
TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
|
||||
ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
|
||||
ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
|
||||
ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
|
||||
ctx->Const.MaxTextureImageUnits);
|
||||
ctx->Const.MaxVertexTextureImageUnits = 0; /* no vertex shader textures */
|
||||
|
||||
/* Mesa limits textures to 4kx4k; it would be nice to fix that someday
|
||||
*/
|
||||
ctx->Const.MaxTextureLevels = 13;
|
||||
ctx->Const.Max3DTextureLevels = 9;
|
||||
ctx->Const.MaxCubeTextureLevels = 12;
|
||||
ctx->Const.MaxTextureRectSize = (1<<12);
|
||||
|
||||
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
|
||||
|
||||
/* if conformance mode is set, swrast can handle any size AA point */
|
||||
ctx->Const.MaxPointSizeAA = 255.0;
|
||||
|
||||
/* We want the GLSL compiler to emit code that uses condition codes */
|
||||
ctx->Shader.EmitCondCodes = GL_TRUE;
|
||||
ctx->Shader.EmitNVTempInitialization = GL_TRUE;
|
||||
|
||||
ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
|
||||
ctx->Const.VertexProgram.MaxAluInstructions = 0;
|
||||
ctx->Const.VertexProgram.MaxTexInstructions = 0;
|
||||
ctx->Const.VertexProgram.MaxTexIndirections = 0;
|
||||
ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
|
||||
ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
|
||||
ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
|
||||
ctx->Const.VertexProgram.MaxNativeAttribs = 16;
|
||||
ctx->Const.VertexProgram.MaxNativeTemps = 256;
|
||||
ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
|
||||
ctx->Const.VertexProgram.MaxNativeParameters = 1024;
|
||||
ctx->Const.VertexProgram.MaxEnvParams =
|
||||
MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
|
||||
ctx->Const.VertexProgram.MaxEnvParams);
|
||||
|
||||
ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
|
||||
ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
|
||||
ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
|
||||
ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
|
||||
ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
|
||||
ctx->Const.FragmentProgram.MaxNativeTemps = 256;
|
||||
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
|
||||
ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
|
||||
ctx->Const.FragmentProgram.MaxEnvParams =
|
||||
MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
|
||||
ctx->Const.FragmentProgram.MaxEnvParams);
|
||||
|
||||
brw_init_query( brw );
|
||||
brw_init_state( brw );
|
||||
brw_draw_init( brw );
|
||||
|
||||
brw->state.dirty.mesa = ~0;
|
||||
brw->state.dirty.brw = ~0;
|
||||
|
||||
brw->emit_state_always = 0;
|
||||
|
||||
ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
|
||||
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
|
||||
|
||||
make_empty_list(&brw->query.active_head);
|
||||
|
||||
brw_draw_init( brw );
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* called from intelDestroyContext()
|
||||
*/
|
||||
static void brw_destroy_context( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
int i;
|
||||
|
||||
brw_destroy_state(brw);
|
||||
brw_draw_destroy( brw );
|
||||
|
||||
_mesa_free(brw->wm.compile_data);
|
||||
|
||||
for (i = 0; i < brw->state.nr_color_regions; i++)
|
||||
intel_region_release(&brw->state.color_regions[i]);
|
||||
brw->state.nr_color_regions = 0;
|
||||
intel_region_release(&brw->state.depth_region);
|
||||
|
||||
dri_bo_unreference(brw->curbe.curbe_bo);
|
||||
dri_bo_unreference(brw->vs.prog_bo);
|
||||
dri_bo_unreference(brw->vs.state_bo);
|
||||
dri_bo_unreference(brw->vs.bind_bo);
|
||||
dri_bo_unreference(brw->gs.prog_bo);
|
||||
dri_bo_unreference(brw->gs.state_bo);
|
||||
dri_bo_unreference(brw->clip.prog_bo);
|
||||
dri_bo_unreference(brw->clip.state_bo);
|
||||
dri_bo_unreference(brw->clip.vp_bo);
|
||||
dri_bo_unreference(brw->sf.prog_bo);
|
||||
dri_bo_unreference(brw->sf.state_bo);
|
||||
dri_bo_unreference(brw->sf.vp_bo);
|
||||
for (i = 0; i < BRW_MAX_TEX_UNIT; i++)
|
||||
dri_bo_unreference(brw->wm.sdc_bo[i]);
|
||||
dri_bo_unreference(brw->wm.bind_bo);
|
||||
for (i = 0; i < BRW_WM_MAX_SURF; i++)
|
||||
dri_bo_unreference(brw->wm.surf_bo[i]);
|
||||
dri_bo_unreference(brw->wm.sampler_bo);
|
||||
dri_bo_unreference(brw->wm.prog_bo);
|
||||
dri_bo_unreference(brw->wm.state_bo);
|
||||
dri_bo_unreference(brw->cc.prog_bo);
|
||||
dri_bo_unreference(brw->cc.state_bo);
|
||||
dri_bo_unreference(brw->cc.vp_bo);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
* Handles blending and (presumably) depth and stencil testing.
|
||||
*/
|
||||
|
||||
#define BRW_FALLBACK_TEXTURE 0x1
|
||||
#define BRW_MAX_CURBE (32*16)
|
||||
|
||||
struct brw_context;
|
||||
@@ -450,11 +449,9 @@ struct brw_query_object {
|
||||
*/
|
||||
struct brw_context
|
||||
{
|
||||
struct intel_context intel; /**< base class, must be first field */
|
||||
GLuint primitive;
|
||||
|
||||
GLboolean emit_state_always;
|
||||
GLboolean tmp_fallback;
|
||||
GLboolean no_batch_wrap;
|
||||
|
||||
struct {
|
||||
@@ -692,7 +689,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
|
||||
/*======================================================================
|
||||
* brw_queryobj.c
|
||||
*/
|
||||
void brw_init_queryobj_functions(struct dd_function_table *functions);
|
||||
void brw_init_query(struct brw_context *brw);
|
||||
void brw_prepare_query_begin(struct brw_context *brw);
|
||||
void brw_emit_query_begin(struct brw_context *brw);
|
||||
void brw_emit_query_end(struct brw_context *brw);
|
||||
@@ -730,7 +727,7 @@ int brw_disasm (FILE *file, struct brw_instruction *inst);
|
||||
* macros used previously:
|
||||
*/
|
||||
static INLINE struct brw_context *
|
||||
brw_context( GLcontext *ctx )
|
||||
brw_context( struct pipe_context *ctx )
|
||||
{
|
||||
return (struct brw_context *)ctx;
|
||||
}
|
||||
|
||||
@@ -30,14 +30,6 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/context.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "shader/prog_statevars.h"
|
||||
#include "intel_batchbuffer.h"
|
||||
#include "intel_regions.h"
|
||||
#include "brw_context.h"
|
||||
@@ -64,31 +56,17 @@ static void calculate_curbe_offsets( struct brw_context *brw )
|
||||
GLuint nr_clip_regs = 0;
|
||||
GLuint total_regs;
|
||||
|
||||
/* _NEW_TRANSFORM */
|
||||
if (ctx->Transform.ClipPlanesEnabled) {
|
||||
GLuint nr_planes = 6 + brw_count_bits(ctx->Transform.ClipPlanesEnabled);
|
||||
/* PIPE_NEW_UCP */
|
||||
if (brw->nr_ucp) {
|
||||
GLuint nr_planes = 6 + brw->nr_ucp;
|
||||
nr_clip_regs = (nr_planes * 4 + 15) / 16;
|
||||
}
|
||||
|
||||
|
||||
total_regs = nr_fp_regs + nr_vp_regs + nr_clip_regs;
|
||||
|
||||
/* This can happen - what to do? Probably rather than falling
|
||||
* back, the best thing to do is emit programs which code the
|
||||
* constants as immediate values. Could do this either as a static
|
||||
* cap on WM and VS, or adaptively.
|
||||
*
|
||||
* Unfortunately, this is currently dependent on the results of the
|
||||
* program generation process (in the case of wm), so this would
|
||||
* introduce the need to re-generate programs in the event of a
|
||||
* curbe allocation failure.
|
||||
*/
|
||||
/* Max size is 32 - just large enough to
|
||||
* hold the 128 parameters allowed by
|
||||
* the fragment and vertex program
|
||||
* api's. It's not clear what happens
|
||||
* when both VP and FP want to use 128
|
||||
* parameters, though.
|
||||
/* When this is > 32, want to use a true constant buffer to hold
|
||||
* the extra constants.
|
||||
*/
|
||||
assert(total_regs <= 32);
|
||||
|
||||
@@ -113,8 +91,8 @@ static void calculate_curbe_offsets( struct brw_context *brw )
|
||||
brw->curbe.vs_size = nr_vp_regs; reg += nr_vp_regs;
|
||||
brw->curbe.total_size = reg;
|
||||
|
||||
if (0)
|
||||
_mesa_printf("curbe wm %d+%d clip %d+%d vs %d+%d\n",
|
||||
if (BRW_DEBUG & DEBUG_CURBE)
|
||||
debug_printf("curbe wm %d+%d clip %d+%d vs %d+%d\n",
|
||||
brw->curbe.wm_start,
|
||||
brw->curbe.wm_size,
|
||||
brw->curbe.clip_start,
|
||||
@@ -129,7 +107,7 @@ static void calculate_curbe_offsets( struct brw_context *brw )
|
||||
|
||||
const struct brw_tracked_state brw_curbe_offsets = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_TRANSFORM,
|
||||
.mesa = PIPE_NEW_UCP,
|
||||
.brw = BRW_NEW_VERTEX_PROGRAM,
|
||||
.cache = CACHE_NEW_WM_PROG
|
||||
},
|
||||
@@ -204,11 +182,13 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||
if (brw->curbe.wm_size) {
|
||||
GLuint offset = brw->curbe.wm_start * 16;
|
||||
|
||||
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
|
||||
/* map fs constant buffer */
|
||||
|
||||
/* copy float constants */
|
||||
for (i = 0; i < brw->wm.prog_data->nr_params; i++)
|
||||
buf[offset + i] = *brw->wm.prog_data->param[i];
|
||||
|
||||
/* unmap fs constant buffer */
|
||||
}
|
||||
|
||||
|
||||
@@ -228,18 +208,15 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||
buf[offset + i * 4 + 3] = fixed_plane[i][3];
|
||||
}
|
||||
|
||||
/* Clip planes: _NEW_TRANSFORM plus _NEW_PROJECTION to get to
|
||||
* clip-space:
|
||||
/* Clip planes:
|
||||
*/
|
||||
assert(MAX_CLIP_PLANES == 6);
|
||||
for (j = 0; j < MAX_CLIP_PLANES; j++) {
|
||||
if (ctx->Transform.ClipPlanesEnabled & (1<<j)) {
|
||||
buf[offset + i * 4 + 0] = ctx->Transform._ClipUserPlane[j][0];
|
||||
buf[offset + i * 4 + 1] = ctx->Transform._ClipUserPlane[j][1];
|
||||
buf[offset + i * 4 + 2] = ctx->Transform._ClipUserPlane[j][2];
|
||||
buf[offset + i * 4 + 3] = ctx->Transform._ClipUserPlane[j][3];
|
||||
i++;
|
||||
}
|
||||
assert(brw->nr_ucp <= 6);
|
||||
for (j = 0; j < brw->nr_ucp; j++) {
|
||||
buf[offset + i * 4 + 0] = brw->ucp[j][0];
|
||||
buf[offset + i * 4 + 1] = brw->ucp[j][1];
|
||||
buf[offset + i * 4 + 2] = brw->ucp[j][2];
|
||||
buf[offset + i * 4 + 3] = brw->ucp[j][3];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,13 +225,7 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||
GLuint offset = brw->curbe.vs_start * 16;
|
||||
GLuint nr = brw->vs.prog_data->nr_params / 4;
|
||||
|
||||
if (brw->vertex_program->IsNVProgram)
|
||||
_mesa_load_tracked_matrices(ctx);
|
||||
|
||||
/* Updates the ParamaterValues[i] pointers for all parameters of the
|
||||
* basic type of PROGRAM_STATE_VAR.
|
||||
*/
|
||||
_mesa_load_state_parameters(ctx, vp->program.Base.Parameters);
|
||||
/* map vs constant buffer */
|
||||
|
||||
/* XXX just use a memcpy here */
|
||||
for (i = 0; i < nr; i++) {
|
||||
@@ -264,14 +235,16 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||
buf[offset + i * 4 + 2] = value[2];
|
||||
buf[offset + i * 4 + 3] = value[3];
|
||||
}
|
||||
|
||||
/* unmap vs constant buffer */
|
||||
}
|
||||
|
||||
if (0) {
|
||||
for (i = 0; i < sz*16; i+=4)
|
||||
_mesa_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4,
|
||||
debug_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4,
|
||||
buf[i+0], buf[i+1], buf[i+2], buf[i+3]);
|
||||
|
||||
_mesa_printf("last_buf %p buf %p sz %d/%d cmp %d\n",
|
||||
debug_printf("last_buf %p buf %p sz %d/%d cmp %d\n",
|
||||
brw->curbe.last_buf, buf,
|
||||
bufsz, brw->curbe.last_bufsz,
|
||||
brw->curbe.last_buf ? memcmp(buf, brw->curbe.last_buf, bufsz) : -1);
|
||||
@@ -282,12 +255,12 @@ static void prepare_constant_buffer(struct brw_context *brw)
|
||||
bufsz == brw->curbe.last_bufsz &&
|
||||
memcmp(buf, brw->curbe.last_buf, bufsz) == 0) {
|
||||
/* constants have not changed */
|
||||
_mesa_free(buf);
|
||||
FREE(buf);
|
||||
}
|
||||
else {
|
||||
/* constants have changed */
|
||||
if (brw->curbe.last_buf)
|
||||
_mesa_free(brw->curbe.last_buf);
|
||||
FREE(brw->curbe.last_buf);
|
||||
|
||||
brw->curbe.last_buf = buf;
|
||||
brw->curbe.last_bufsz = bufsz;
|
||||
@@ -353,15 +326,11 @@ static void emit_constant_buffer(struct brw_context *brw)
|
||||
ADVANCE_BATCH();
|
||||
}
|
||||
|
||||
/* This tracked state is unique in that the state it monitors varies
|
||||
* dynamically depending on the parameters tracked by the fragment and
|
||||
* vertex programs. This is the template used as a starting point,
|
||||
* each context will maintain a copy of this internally and update as
|
||||
* required.
|
||||
*/
|
||||
const struct brw_tracked_state brw_constant_buffer = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_PROGRAM_CONSTANTS,
|
||||
.mesa = (PIPE_NEW_FS_CONSTANTS |
|
||||
PIPE_NEW_VS_CONSTANTS |
|
||||
PIPE_NEW_UCP),
|
||||
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
|
||||
BRW_NEW_VERTEX_PROGRAM |
|
||||
BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */
|
||||
|
||||
@@ -840,8 +840,8 @@
|
||||
|
||||
#include "intel_chipset.h"
|
||||
|
||||
#define BRW_IS_G4X(brw) (IS_G4X((brw)->intel.intelScreen->deviceID))
|
||||
#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->intel.intelScreen->deviceID))
|
||||
#define BRW_IS_G4X(brw) (IS_G4X((brw)->brw_screen->deviceID))
|
||||
#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->brw_screen->deviceID))
|
||||
#define BRW_IS_965(brw) (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)))
|
||||
#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
|
||||
#define CMD_VF_STATISTICS(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "main/mtypes.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
|
||||
@@ -39,14 +39,13 @@
|
||||
#include "brw_defines.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_state.h"
|
||||
#include "brw_fallback.h"
|
||||
|
||||
#include "intel_batchbuffer.h"
|
||||
#include "intel_buffer_objects.h"
|
||||
|
||||
#define FILE_DEBUG_FLAG DEBUG_BATCH
|
||||
|
||||
static GLuint prim_to_hw_prim[GL_POLYGON+1] = {
|
||||
static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = {
|
||||
_3DPRIM_POINTLIST,
|
||||
_3DPRIM_LINELIST,
|
||||
_3DPRIM_LINELOOP,
|
||||
@@ -60,19 +59,6 @@ static GLuint prim_to_hw_prim[GL_POLYGON+1] = {
|
||||
};
|
||||
|
||||
|
||||
static const GLenum reduced_prim[GL_POLYGON+1] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINES,
|
||||
GL_LINES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
/* When the primitive changes, set a state bit and re-validate. Not
|
||||
* the nicest and would rather deal with this by having all the
|
||||
@@ -196,102 +182,6 @@ static void brw_merge_inputs( struct brw_context *brw,
|
||||
brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
|
||||
}
|
||||
|
||||
/* XXX: could split the primitive list to fallback only on the
|
||||
* non-conformant primitives.
|
||||
*/
|
||||
static GLboolean check_fallbacks( struct brw_context *brw,
|
||||
const struct _mesa_prim *prim,
|
||||
GLuint nr_prims )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
GLuint i;
|
||||
|
||||
/* If we don't require strict OpenGL conformance, never
|
||||
* use fallbacks. If we're forcing fallbacks, always
|
||||
* use fallfacks.
|
||||
*/
|
||||
if (brw->intel.conformance_mode == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
if (brw->intel.conformance_mode == 2)
|
||||
return GL_TRUE;
|
||||
|
||||
if (ctx->Polygon.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (reduced_prim[prim[i].mode] == GL_TRIANGLES)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* BRW hardware will do AA lines, but they are non-conformant it
|
||||
* seems. TBD whether we keep this fallback:
|
||||
*/
|
||||
if (ctx->Line.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (reduced_prim[prim[i].mode] == GL_LINES)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Stipple -- these fallbacks could be resolved with a little
|
||||
* bit of work?
|
||||
*/
|
||||
if (ctx->Line.StippleFlag) {
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
/* GS doesn't get enough information to know when to reset
|
||||
* the stipple counter?!?
|
||||
*/
|
||||
if (prim[i].mode == GL_LINE_LOOP || prim[i].mode == GL_LINE_STRIP)
|
||||
return GL_TRUE;
|
||||
|
||||
if (prim[i].mode == GL_POLYGON &&
|
||||
(ctx->Polygon.FrontMode == GL_LINE ||
|
||||
ctx->Polygon.BackMode == GL_LINE))
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Point.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (prim[i].mode == GL_POINTS)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* BRW hardware doesn't handle GL_CLAMP texturing correctly;
|
||||
* brw_wm_sampler_state:translate_wrap_mode() treats GL_CLAMP
|
||||
* as GL_CLAMP_TO_EDGE instead. If we're using GL_CLAMP, and
|
||||
* we want strict conformance, force the fallback.
|
||||
* Right now, we only do this for 2D textures.
|
||||
*/
|
||||
{
|
||||
int u;
|
||||
for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
|
||||
if (texUnit->Enabled) {
|
||||
if (texUnit->Enabled & TEXTURE_1D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_1D_INDEX]->WrapS == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
if (texUnit->Enabled & TEXTURE_2D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapS == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapT == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
if (texUnit->Enabled & TEXTURE_3D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapS == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapT == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapR == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing stopping us from the fast path now */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* May fail if out of video memory for texture or vbo upload, or on
|
||||
* fallback conditions.
|
||||
*/
|
||||
@@ -308,23 +198,12 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
GLboolean retval = GL_FALSE;
|
||||
GLboolean warn = GL_FALSE;
|
||||
GLboolean first_time = GL_TRUE;
|
||||
uint32_t hw_prim;
|
||||
GLuint i;
|
||||
|
||||
if (ctx->NewState)
|
||||
_mesa_update_state( ctx );
|
||||
|
||||
/* We have to validate the textures *before* checking for fallbacks;
|
||||
* otherwise, the software fallback won't be able to rely on the
|
||||
* texture state, the firstLevel and lastLevel fields won't be
|
||||
* set in the intel texture object (they'll both be 0), and the
|
||||
* software fallback will segfault if it attempts to access any
|
||||
* texture level other than level 0.
|
||||
*/
|
||||
brw_validate_textures( brw );
|
||||
|
||||
if (check_fallbacks(brw, prim, nr_prims))
|
||||
return GL_FALSE;
|
||||
|
||||
/* Bind all inputs, derive varying and size information:
|
||||
*/
|
||||
brw_merge_inputs( brw, arrays );
|
||||
@@ -336,90 +215,30 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
brw->vb.max_index = max_index;
|
||||
brw->state.dirty.brw |= BRW_NEW_VERTICES;
|
||||
|
||||
/* Have to validate state quite late. Will rebuild tnl_program,
|
||||
* which depends on varying information.
|
||||
*
|
||||
* Note this is where brw->vs->prog_data.inputs_read is calculated,
|
||||
* so can't access it earlier.
|
||||
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
|
||||
* flush otherwise.
|
||||
*/
|
||||
ret = dri_bufmgr_check_aperture_space(brw->state.validated_bos,
|
||||
brw->state.validated_bo_count);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
|
||||
if (!intel->constant_cliprect && intel->driDrawable->numClipRects == 0) {
|
||||
UNLOCK_HARDWARE(intel);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
uint32_t hw_prim;
|
||||
|
||||
/* Flush the batch if it's approaching full, so that we don't wrap while
|
||||
* we've got validated state that needs to be in the same batch as the
|
||||
* primitives. This fraction is just a guess (minimal full state plus
|
||||
* a primitive is around 512 bytes), and would be better if we had
|
||||
* an upper bound of how much we might emit in a single
|
||||
* brw_try_draw_prims().
|
||||
*/
|
||||
intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
|
||||
LOOP_CLIPRECTS);
|
||||
|
||||
hw_prim = brw_set_prim(brw, prim[i].mode);
|
||||
|
||||
if (first_time || (brw->state.dirty.brw & BRW_NEW_PRIMITIVE)) {
|
||||
first_time = GL_FALSE;
|
||||
|
||||
brw_validate_state(brw);
|
||||
|
||||
/* Various fallback checks: */
|
||||
if (brw->intel.Fallback)
|
||||
goto out;
|
||||
|
||||
/* Check that we can fit our state in with our existing batchbuffer, or
|
||||
* flush otherwise.
|
||||
*/
|
||||
if (dri_bufmgr_check_aperture_space(brw->state.validated_bos,
|
||||
brw->state.validated_bo_count)) {
|
||||
static GLboolean warned;
|
||||
intel_batchbuffer_flush(intel->batch);
|
||||
|
||||
/* Validate the state after we flushed the batch (which would have
|
||||
* changed the set of dirty state). If we still fail to
|
||||
* check_aperture, warn of what's happening, but attempt to continue
|
||||
* on since it may succeed anyway, and the user would probably rather
|
||||
* see a failure and a warning than a fallback.
|
||||
*/
|
||||
brw_validate_state(brw);
|
||||
if (!warned &&
|
||||
dri_bufmgr_check_aperture_space(brw->state.validated_bos,
|
||||
brw->state.validated_bo_count)) {
|
||||
warn = GL_TRUE;
|
||||
warned = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
brw_upload_state(brw);
|
||||
}
|
||||
|
||||
brw_emit_prim(brw, &prim[i], hw_prim);
|
||||
|
||||
retval = GL_TRUE;
|
||||
}
|
||||
ret = brw_upload_state(brw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = brw_emit_prim(brw, &prim[i], hw_prim);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (intel->always_flush_batch)
|
||||
intel_batchbuffer_flush(intel->batch);
|
||||
out:
|
||||
UNLOCK_HARDWARE(intel);
|
||||
|
||||
brw_state_cache_check_size(brw);
|
||||
|
||||
if (warn)
|
||||
fprintf(stderr, "i965: Single primitive emit potentially exceeded "
|
||||
"available aperture space\n");
|
||||
|
||||
if (!retval)
|
||||
DBG("%s failed\n", __FUNCTION__);
|
||||
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brw_draw_prims( GLcontext *ctx,
|
||||
@@ -431,37 +250,26 @@ void brw_draw_prims( GLcontext *ctx,
|
||||
GLuint min_index,
|
||||
GLuint max_index )
|
||||
{
|
||||
GLboolean retval;
|
||||
enum pipe_error ret;
|
||||
|
||||
if (!vbo_all_varyings_in_vbos(arrays)) {
|
||||
if (!index_bounds_valid)
|
||||
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
|
||||
|
||||
/* Decide if we want to rebase. If so we end up recursing once
|
||||
* only into this function.
|
||||
*/
|
||||
if (min_index != 0) {
|
||||
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);
|
||||
ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
||||
|
||||
/* Otherwise, we really are out of memory. Pass the drawing
|
||||
* command to the software tnl module and which will in turn call
|
||||
* swrast to do the drawing.
|
||||
*/
|
||||
if (!retval) {
|
||||
_swsetup_Wakeup(ctx);
|
||||
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
||||
if (ret != 0) {
|
||||
intel_batchbuffer_flush(intel->batch);
|
||||
ret = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void brw_draw_init( struct brw_context *brw )
|
||||
|
||||
@@ -25,13 +25,9 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/bufferobj.h"
|
||||
#include "main/context.h"
|
||||
#include "main/state.h"
|
||||
#include "main/api_validate.h"
|
||||
#include "main/enums.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "brw_draw.h"
|
||||
#include "brw_defines.h"
|
||||
@@ -43,303 +39,157 @@
|
||||
#include "intel_buffer_objects.h"
|
||||
#include "intel_tex.h"
|
||||
|
||||
static GLuint double_types[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R64_FLOAT,
|
||||
BRW_SURFACEFORMAT_R64G64_FLOAT,
|
||||
BRW_SURFACEFORMAT_R64G64B64_FLOAT,
|
||||
BRW_SURFACEFORMAT_R64G64B64A64_FLOAT
|
||||
};
|
||||
|
||||
static GLuint float_types[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R32_FLOAT,
|
||||
BRW_SURFACEFORMAT_R32G32_FLOAT,
|
||||
BRW_SURFACEFORMAT_R32G32B32_FLOAT,
|
||||
BRW_SURFACEFORMAT_R32G32B32A32_FLOAT
|
||||
};
|
||||
|
||||
static GLuint uint_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R32_UNORM,
|
||||
BRW_SURFACEFORMAT_R32G32_UNORM,
|
||||
BRW_SURFACEFORMAT_R32G32B32_UNORM,
|
||||
BRW_SURFACEFORMAT_R32G32B32A32_UNORM
|
||||
};
|
||||
|
||||
static GLuint uint_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R32_USCALED,
|
||||
BRW_SURFACEFORMAT_R32G32_USCALED,
|
||||
BRW_SURFACEFORMAT_R32G32B32_USCALED,
|
||||
BRW_SURFACEFORMAT_R32G32B32A32_USCALED
|
||||
};
|
||||
|
||||
static GLuint int_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R32_SNORM,
|
||||
BRW_SURFACEFORMAT_R32G32_SNORM,
|
||||
BRW_SURFACEFORMAT_R32G32B32_SNORM,
|
||||
BRW_SURFACEFORMAT_R32G32B32A32_SNORM
|
||||
};
|
||||
|
||||
static GLuint int_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R32_SSCALED,
|
||||
BRW_SURFACEFORMAT_R32G32_SSCALED,
|
||||
BRW_SURFACEFORMAT_R32G32B32_SSCALED,
|
||||
BRW_SURFACEFORMAT_R32G32B32A32_SSCALED
|
||||
};
|
||||
|
||||
static GLuint ushort_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R16_UNORM,
|
||||
BRW_SURFACEFORMAT_R16G16_UNORM,
|
||||
BRW_SURFACEFORMAT_R16G16B16_UNORM,
|
||||
BRW_SURFACEFORMAT_R16G16B16A16_UNORM
|
||||
};
|
||||
|
||||
static GLuint ushort_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R16_USCALED,
|
||||
BRW_SURFACEFORMAT_R16G16_USCALED,
|
||||
BRW_SURFACEFORMAT_R16G16B16_USCALED,
|
||||
BRW_SURFACEFORMAT_R16G16B16A16_USCALED
|
||||
};
|
||||
|
||||
static GLuint short_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R16_SNORM,
|
||||
BRW_SURFACEFORMAT_R16G16_SNORM,
|
||||
BRW_SURFACEFORMAT_R16G16B16_SNORM,
|
||||
BRW_SURFACEFORMAT_R16G16B16A16_SNORM
|
||||
};
|
||||
|
||||
static GLuint short_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R16_SSCALED,
|
||||
BRW_SURFACEFORMAT_R16G16_SSCALED,
|
||||
BRW_SURFACEFORMAT_R16G16B16_SSCALED,
|
||||
BRW_SURFACEFORMAT_R16G16B16A16_SSCALED
|
||||
};
|
||||
|
||||
static GLuint ubyte_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R8_UNORM,
|
||||
BRW_SURFACEFORMAT_R8G8_UNORM,
|
||||
BRW_SURFACEFORMAT_R8G8B8_UNORM,
|
||||
BRW_SURFACEFORMAT_R8G8B8A8_UNORM
|
||||
};
|
||||
|
||||
static GLuint ubyte_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R8_USCALED,
|
||||
BRW_SURFACEFORMAT_R8G8_USCALED,
|
||||
BRW_SURFACEFORMAT_R8G8B8_USCALED,
|
||||
BRW_SURFACEFORMAT_R8G8B8A8_USCALED
|
||||
};
|
||||
|
||||
static GLuint byte_types_norm[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R8_SNORM,
|
||||
BRW_SURFACEFORMAT_R8G8_SNORM,
|
||||
BRW_SURFACEFORMAT_R8G8B8_SNORM,
|
||||
BRW_SURFACEFORMAT_R8G8B8A8_SNORM
|
||||
};
|
||||
|
||||
static GLuint byte_types_scale[5] = {
|
||||
0,
|
||||
BRW_SURFACEFORMAT_R8_SSCALED,
|
||||
BRW_SURFACEFORMAT_R8G8_SSCALED,
|
||||
BRW_SURFACEFORMAT_R8G8B8_SSCALED,
|
||||
BRW_SURFACEFORMAT_R8G8B8A8_SSCALED
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Given vertex array type/size/format/normalized info, return
|
||||
* the appopriate hardware surface type.
|
||||
* Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays.
|
||||
*/
|
||||
static GLuint get_surface_type( GLenum type, GLuint size,
|
||||
GLenum format, GLboolean normalized )
|
||||
|
||||
unsigned brw_translate_surface_format( unsigned id )
|
||||
{
|
||||
if (INTEL_DEBUG & DEBUG_VERTS)
|
||||
_mesa_printf("type %s size %d normalized %d\n",
|
||||
_mesa_lookup_enum_by_nr(type), size, normalized);
|
||||
switch (id) {
|
||||
case PIPE_FORMAT_R64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64B64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
|
||||
case PIPE_FORMAT_R64G64B64A64_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
|
||||
|
||||
if (normalized) {
|
||||
switch (type) {
|
||||
case GL_DOUBLE: return double_types[size];
|
||||
case GL_FLOAT: return float_types[size];
|
||||
case GL_INT: return int_types_norm[size];
|
||||
case GL_SHORT: return short_types_norm[size];
|
||||
case GL_BYTE: return byte_types_norm[size];
|
||||
case GL_UNSIGNED_INT: return uint_types_norm[size];
|
||||
case GL_UNSIGNED_SHORT: return ushort_types_norm[size];
|
||||
case GL_UNSIGNED_BYTE:
|
||||
if (format == GL_BGRA) {
|
||||
/* See GL_EXT_vertex_array_bgra */
|
||||
assert(size == 4);
|
||||
return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
else {
|
||||
return ubyte_types_norm[size];
|
||||
}
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(format == GL_RGBA); /* sanity check */
|
||||
switch (type) {
|
||||
case GL_DOUBLE: return double_types[size];
|
||||
case GL_FLOAT: return float_types[size];
|
||||
case GL_INT: return int_types_scale[size];
|
||||
case GL_SHORT: return short_types_scale[size];
|
||||
case GL_BYTE: return byte_types_scale[size];
|
||||
case GL_UNSIGNED_INT: return uint_types_scale[size];
|
||||
case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
|
||||
case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
case PIPE_FORMAT_R32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32_UNORM;
|
||||
case PIPE_FORMAT_R32G32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32_UNORM;
|
||||
case PIPE_FORMAT_R32G32B32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_UNORM;
|
||||
case PIPE_FORMAT_R32G32B32A32_UNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32_USCALED;
|
||||
case PIPE_FORMAT_R32G32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32_USCALED;
|
||||
case PIPE_FORMAT_R32G32B32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_USCALED;
|
||||
case PIPE_FORMAT_R32G32B32A32_USCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32_SNORM;
|
||||
case PIPE_FORMAT_R32G32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32_SNORM;
|
||||
case PIPE_FORMAT_R32G32B32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_SNORM;
|
||||
case PIPE_FORMAT_R32G32B32A32_SNORM:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32B32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
|
||||
case PIPE_FORMAT_R32G32B32A32_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
|
||||
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16_UNORM;
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16_UNORM;
|
||||
case PIPE_FORMAT_R16G16B16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_UNORM;
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16_USCALED;
|
||||
case PIPE_FORMAT_R16G16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16_USCALED;
|
||||
case PIPE_FORMAT_R16G16B16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_USCALED;
|
||||
case PIPE_FORMAT_R16G16B16A16_USCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16_SNORM;
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16_SNORM;
|
||||
case PIPE_FORMAT_R16G16B16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_SNORM;
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16B16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
|
||||
case PIPE_FORMAT_R16G16B16A16_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
|
||||
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8_UNORM;
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8_UNORM;
|
||||
case PIPE_FORMAT_R8G8B8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_UNORM;
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8_USCALED;
|
||||
case PIPE_FORMAT_R8G8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8_USCALED;
|
||||
case PIPE_FORMAT_R8G8B8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_USCALED;
|
||||
case PIPE_FORMAT_R8G8B8A8_USCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
|
||||
|
||||
case PIPE_FORMAT_R8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8_SNORM;
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8_SNORM;
|
||||
case PIPE_FORMAT_R8G8B8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_SNORM;
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
|
||||
|
||||
case PIPE_FORMAT_R8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8B8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
|
||||
case PIPE_FORMAT_R8G8B8A8_SSCALED:
|
||||
return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GLuint get_size( GLenum type )
|
||||
static unsigned get_index_type(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case GL_DOUBLE: return sizeof(GLdouble);
|
||||
case GL_FLOAT: return sizeof(GLfloat);
|
||||
case GL_INT: return sizeof(GLint);
|
||||
case GL_SHORT: return sizeof(GLshort);
|
||||
case GL_BYTE: return sizeof(GLbyte);
|
||||
case GL_UNSIGNED_INT: return sizeof(GLuint);
|
||||
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
|
||||
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint get_index_type(GLenum type)
|
||||
{
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE: return BRW_INDEX_BYTE;
|
||||
case GL_UNSIGNED_SHORT: return BRW_INDEX_WORD;
|
||||
case GL_UNSIGNED_INT: return BRW_INDEX_DWORD;
|
||||
case 1: return BRW_INDEX_BYTE;
|
||||
case 2: return BRW_INDEX_WORD;
|
||||
case 4: return BRW_INDEX_DWORD;
|
||||
default: assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void wrap_buffers( struct brw_context *brw,
|
||||
GLuint size )
|
||||
{
|
||||
if (size < BRW_UPLOAD_INIT_SIZE)
|
||||
size = BRW_UPLOAD_INIT_SIZE;
|
||||
|
||||
brw->vb.upload.offset = 0;
|
||||
|
||||
if (brw->vb.upload.bo != NULL)
|
||||
dri_bo_unreference(brw->vb.upload.bo);
|
||||
brw->vb.upload.bo = dri_bo_alloc(brw->intel.bufmgr, "temporary VBO",
|
||||
size, 1);
|
||||
|
||||
/* Set the internal VBO\ to no-backing-store. We only use them as a
|
||||
* temporary within a brw_try_draw_prims while the lock is held.
|
||||
*/
|
||||
/* DON'T DO THIS AS IF WE HAVE TO RE-ORG MEMORY WE NEED SOMEWHERE WITH
|
||||
FAKE TO PUSH THIS STUFF */
|
||||
// if (!brw->intel.ttm)
|
||||
// dri_bo_fake_disable_backing_store(brw->vb.upload.bo, NULL, NULL);
|
||||
}
|
||||
|
||||
static void get_space( struct brw_context *brw,
|
||||
GLuint size,
|
||||
dri_bo **bo_return,
|
||||
GLuint *offset_return )
|
||||
{
|
||||
size = ALIGN(size, 64);
|
||||
|
||||
if (brw->vb.upload.bo == NULL ||
|
||||
brw->vb.upload.offset + size > brw->vb.upload.bo->size) {
|
||||
wrap_buffers(brw, size);
|
||||
}
|
||||
|
||||
assert(*bo_return == NULL);
|
||||
dri_bo_reference(brw->vb.upload.bo);
|
||||
*bo_return = brw->vb.upload.bo;
|
||||
*offset_return = brw->vb.upload.offset;
|
||||
brw->vb.upload.offset += size;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_array_to_vbo_array( struct brw_context *brw,
|
||||
struct brw_vertex_element *element,
|
||||
GLuint dst_stride)
|
||||
{
|
||||
struct intel_context *intel = &brw->intel;
|
||||
GLuint size = element->count * dst_stride;
|
||||
|
||||
get_space(brw, size, &element->bo, &element->offset);
|
||||
|
||||
if (element->glarray->StrideB == 0) {
|
||||
assert(element->count == 1);
|
||||
element->stride = 0;
|
||||
} else {
|
||||
element->stride = dst_stride;
|
||||
}
|
||||
|
||||
if (dst_stride == element->glarray->StrideB) {
|
||||
if (intel->intelScreen->kernel_exec_fencing) {
|
||||
drm_intel_gem_bo_map_gtt(element->bo);
|
||||
memcpy((char *)element->bo->virtual + element->offset,
|
||||
element->glarray->Ptr, size);
|
||||
drm_intel_gem_bo_unmap_gtt(element->bo);
|
||||
} else {
|
||||
dri_bo_subdata(element->bo,
|
||||
element->offset,
|
||||
size,
|
||||
element->glarray->Ptr);
|
||||
}
|
||||
} else {
|
||||
char *dest;
|
||||
const unsigned char *src = element->glarray->Ptr;
|
||||
int i;
|
||||
|
||||
if (intel->intelScreen->kernel_exec_fencing) {
|
||||
drm_intel_gem_bo_map_gtt(element->bo);
|
||||
dest = element->bo->virtual;
|
||||
dest += element->offset;
|
||||
|
||||
for (i = 0; i < element->count; i++) {
|
||||
memcpy(dest, src, dst_stride);
|
||||
src += element->glarray->StrideB;
|
||||
dest += dst_stride;
|
||||
}
|
||||
|
||||
drm_intel_gem_bo_unmap_gtt(element->bo);
|
||||
} else {
|
||||
void *data;
|
||||
|
||||
data = _mesa_malloc(dst_stride * element->count);
|
||||
dest = data;
|
||||
for (i = 0; i < element->count; i++) {
|
||||
memcpy(dest, src, dst_stride);
|
||||
src += element->glarray->StrideB;
|
||||
dest += dst_stride;
|
||||
}
|
||||
|
||||
dri_bo_subdata(element->bo,
|
||||
element->offset,
|
||||
size,
|
||||
data);
|
||||
|
||||
_mesa_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void brw_prepare_vertices(struct brw_context *brw)
|
||||
static boolean brw_prepare_vertices(struct brw_context *brw)
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
@@ -358,123 +208,38 @@ static void brw_prepare_vertices(struct brw_context *brw)
|
||||
if (0)
|
||||
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
|
||||
|
||||
/* Accumulate the list of enabled arrays. */
|
||||
brw->vb.nr_enabled = 0;
|
||||
while (vs_inputs) {
|
||||
GLuint i = _mesa_ffsll(vs_inputs) - 1;
|
||||
struct brw_vertex_element *input = &brw->vb.inputs[i];
|
||||
|
||||
vs_inputs &= ~(1 << i);
|
||||
brw->vb.enabled[brw->vb.nr_enabled++] = input;
|
||||
}
|
||||
|
||||
/* XXX: In the rare cases where this happens we fallback all
|
||||
* the way to software rasterization, although a tnl fallback
|
||||
* would be sufficient. I don't know of *any* real world
|
||||
* cases with > 17 vertex attributes enabled, so it probably
|
||||
* isn't an issue at this point.
|
||||
*/
|
||||
if (brw->vb.nr_enabled >= BRW_VEP_MAX) {
|
||||
intel->Fallback = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < brw->vb.nr_enabled; i++) {
|
||||
struct brw_vertex_element *input = brw->vb.enabled[i];
|
||||
|
||||
input->element_size = get_size(input->glarray->Type) * input->glarray->Size;
|
||||
|
||||
if (_mesa_is_bufferobj(input->glarray->BufferObj)) {
|
||||
struct intel_buffer_object *intel_buffer =
|
||||
intel_buffer_object(input->glarray->BufferObj);
|
||||
|
||||
/* Named buffer object: Just reference its contents directly. */
|
||||
dri_bo_unreference(input->bo);
|
||||
input->bo = intel_bufferobj_buffer(intel, intel_buffer,
|
||||
INTEL_READ);
|
||||
dri_bo_reference(input->bo);
|
||||
input->offset = (unsigned long)input->glarray->Ptr;
|
||||
input->stride = input->glarray->StrideB;
|
||||
input->count = input->glarray->_MaxElement;
|
||||
|
||||
/* This is a common place to reach if the user mistakenly supplies
|
||||
* a pointer in place of a VBO offset. If we just let it go through,
|
||||
* we may end up dereferencing a pointer beyond the bounds of the
|
||||
* GTT. We would hope that the VBO's max_index would save us, but
|
||||
* Mesa appears to hand us min/max values not clipped to the
|
||||
* array object's _MaxElement, and _MaxElement frequently appears
|
||||
* to be wrong anyway.
|
||||
*
|
||||
* The VBO spec allows application termination in this case, and it's
|
||||
* probably a service to the poor programmer to do so rather than
|
||||
* trying to just not render.
|
||||
*/
|
||||
assert(input->offset < input->bo->size);
|
||||
} else {
|
||||
input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
|
||||
if (input->bo != NULL) {
|
||||
/* Already-uploaded vertex data is present from a previous
|
||||
* prepare_vertices, but we had to re-validate state due to
|
||||
* check_aperture failing and a new batch being produced.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Queue the buffer object up to be uploaded in the next pass,
|
||||
* when we've decided if we're doing interleaved or not.
|
||||
*/
|
||||
if (input->attrib == VERT_ATTRIB_POS) {
|
||||
/* Position array not properly enabled:
|
||||
*/
|
||||
if (input->glarray->StrideB == 0) {
|
||||
intel->Fallback = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
interleave = input->glarray->StrideB;
|
||||
ptr = input->glarray->Ptr;
|
||||
}
|
||||
else if (interleave != input->glarray->StrideB ||
|
||||
(const unsigned char *)input->glarray->Ptr - ptr < 0 ||
|
||||
(const unsigned char *)input->glarray->Ptr - ptr > interleave)
|
||||
{
|
||||
interleave = 0;
|
||||
}
|
||||
|
||||
upload[nr_uploads++] = input;
|
||||
|
||||
/* We rebase drawing to start at element zero only when
|
||||
* varyings are not in vbos, which means we can end up
|
||||
* uploading non-varying arrays (stride != 0) when min_index
|
||||
* is zero. This doesn't matter as the amount to upload is
|
||||
* the same for these arrays whether the draw call is rebased
|
||||
* or not - we just have to upload the one element.
|
||||
*/
|
||||
assert(min_index == 0 || input->glarray->StrideB == 0);
|
||||
if (brw_is_user_buffer(vb)) {
|
||||
u_upload_buffer( brw->upload,
|
||||
min_index * vb->stride,
|
||||
(max_index + 1 - min_index) * vb->stride,
|
||||
&offset,
|
||||
&buffer );
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle any arrays to be uploaded. */
|
||||
if (nr_uploads > 1 && interleave && interleave <= 256) {
|
||||
/* All uploads are interleaved, so upload the arrays together as
|
||||
* interleaved. First, upload the contents and set up upload[0].
|
||||
*/
|
||||
copy_array_to_vbo_array(brw, upload[0], interleave);
|
||||
|
||||
for (i = 1; i < nr_uploads; i++) {
|
||||
/* Then, just point upload[i] at upload[0]'s buffer. */
|
||||
upload[i]->stride = interleave;
|
||||
upload[i]->offset = upload[0]->offset +
|
||||
((const unsigned char *)upload[i]->glarray->Ptr - ptr);
|
||||
upload[i]->bo = upload[0]->bo;
|
||||
dri_bo_reference(upload[i]->bo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Upload non-interleaved arrays */
|
||||
for (i = 0; i < nr_uploads; i++) {
|
||||
copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
|
||||
else
|
||||
{
|
||||
offset = 0;
|
||||
buffer = vb->buffer;
|
||||
count = stride == 0 ? 1 : max_index + 1 - min_index;
|
||||
}
|
||||
|
||||
/* Named buffer object: Just reference its contents directly. */
|
||||
dri_bo_unreference(input->bo);
|
||||
input->bo = intel_bufferobj_buffer(intel, intel_buffer,
|
||||
INTEL_READ);
|
||||
dri_bo_reference(input->bo);
|
||||
|
||||
input->offset = (unsigned long)offset;
|
||||
input->stride = vb->stride;
|
||||
input->count = count;
|
||||
|
||||
assert(input->offset < input->bo->size);
|
||||
}
|
||||
|
||||
brw_prepare_query_begin(brw);
|
||||
@@ -632,13 +397,8 @@ static void brw_prepare_indices(struct brw_context *brw)
|
||||
|
||||
/* Straight upload
|
||||
*/
|
||||
if (intel->intelScreen->kernel_exec_fencing) {
|
||||
drm_intel_gem_bo_map_gtt(bo);
|
||||
memcpy((char *)bo->virtual + offset, index_buffer->ptr, ib_size);
|
||||
drm_intel_gem_bo_unmap_gtt(bo);
|
||||
} else {
|
||||
dri_bo_subdata(bo, offset, ib_size, index_buffer->ptr);
|
||||
}
|
||||
brw_bo_subdata(bo, offset, ib_size, index_buffer->ptr);
|
||||
|
||||
} else {
|
||||
offset = (GLuint) (unsigned long) index_buffer->ptr;
|
||||
brw->ib.start_vertex_offset = 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ static void compile_gs_prog( struct brw_context *brw,
|
||||
/* Need to locate the two positions present in vertex + header.
|
||||
* These are currently hardcoded:
|
||||
*/
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
c.nr_attrs = util_count_bits(c.key.attrs);
|
||||
|
||||
if (BRW_IS_IGDNG(brw))
|
||||
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (key->logic_op != GL_COPY) {
|
||||
cc.cc2.logicop_enable = 1;
|
||||
cc.cc5.logicop_func = intel_translate_logic_op(key->logic_op);
|
||||
} else if (key->color_blend) {
|
||||
GLenum eqRGB = key->blend_eq_rgb;
|
||||
GLenum eqA = key->blend_eq_a;
|
||||
GLenum srcRGB = key->blend_src_rgb;
|
||||
GLenum dstRGB = key->blend_dst_rgb;
|
||||
GLenum srcA = key->blend_src_a;
|
||||
GLenum dstA = key->blend_dst_a;
|
||||
|
||||
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
|
||||
srcRGB = dstRGB = GL_ONE;
|
||||
}
|
||||
|
||||
if (eqA == GL_MIN || eqA == GL_MAX) {
|
||||
srcA = dstA = GL_ONE;
|
||||
}
|
||||
|
||||
cc.cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
|
||||
cc.cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
|
||||
cc.cc6.blend_function = brw_translate_blend_equation(eqRGB);
|
||||
|
||||
cc.cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
|
||||
cc.cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
|
||||
cc.cc5.ia_blend_function = brw_translate_blend_equation(eqA);
|
||||
|
||||
cc.cc3.blend_enable = 1;
|
||||
cc.cc3.ia_blend_enable = (srcA != srcRGB ||
|
||||
dstA != dstRGB ||
|
||||
eqA != eqRGB);
|
||||
}
|
||||
|
||||
if (key->dither) {
|
||||
cc.cc5.dither_enable = 1;
|
||||
cc.cc6.y_dither_offset = 0;
|
||||
cc.cc6.x_dither_offset = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
if (INTEL_DEBUG & DEBUG_STATS)
|
||||
cc.cc5.statistics_enable = 1;
|
||||
@@ -0,0 +1,52 @@
|
||||
/* _NEW_STENCIL */
|
||||
if (key->dsa.stencil[0].enable) {
|
||||
cc.cc0.stencil_enable = 1;
|
||||
cc.cc0.stencil_func =
|
||||
intel_translate_compare_func(key->stencil_func[0]);
|
||||
cc.cc0.stencil_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_fail_op[0]);
|
||||
cc.cc0.stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[0]);
|
||||
cc.cc0.stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[0]);
|
||||
cc.cc1.stencil_ref = key->stencil_ref[0];
|
||||
cc.cc1.stencil_write_mask = key->stencil_write_mask[0];
|
||||
cc.cc1.stencil_test_mask = key->stencil_test_mask[0];
|
||||
|
||||
if (key->stencil_two_side) {
|
||||
cc.cc0.bf_stencil_enable = 1;
|
||||
cc.cc0.bf_stencil_func =
|
||||
intel_translate_compare_func(key->stencil_func[1]);
|
||||
cc.cc0.bf_stencil_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_fail_op[1]);
|
||||
cc.cc0.bf_stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[1]);
|
||||
cc.cc0.bf_stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[1]);
|
||||
cc.cc1.bf_stencil_ref = key->stencil_ref[1];
|
||||
cc.cc2.bf_stencil_write_mask = key->stencil_write_mask[1];
|
||||
cc.cc2.bf_stencil_test_mask = key->stencil_test_mask[1];
|
||||
}
|
||||
|
||||
/* Not really sure about this:
|
||||
*/
|
||||
if (key->stencil_write_mask[0] ||
|
||||
(key->stencil_two_side && key->stencil_write_mask[1]))
|
||||
cc.cc0.stencil_write_enable = 1;
|
||||
}
|
||||
|
||||
|
||||
if (key->alpha_enabled) {
|
||||
cc.cc3.alpha_test = 1;
|
||||
cc.cc3.alpha_test_func = intel_translate_compare_func(key->alpha_func);
|
||||
cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
|
||||
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc.cc7.alpha_ref.ub[0], key->alpha_ref);
|
||||
}
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
if (key->depth_test) {
|
||||
cc.cc2.depth_test = 1;
|
||||
cc.cc2.depth_test_function = intel_translate_compare_func(key->depth_func);
|
||||
cc.cc2.depth_write_enable = key->depth_write;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
/**
|
||||
* called from intelDrawBuffer()
|
||||
*/
|
||||
static void brw_set_draw_region( struct intel_context *intel,
|
||||
struct intel_region *color_regions[],
|
||||
struct intel_region *depth_region,
|
||||
GLuint num_color_regions)
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
GLuint i;
|
||||
|
||||
/* release old color/depth regions */
|
||||
if (brw->state.depth_region != depth_region)
|
||||
brw->state.dirty.brw |= BRW_NEW_DEPTH_BUFFER;
|
||||
for (i = 0; i < brw->state.nr_color_regions; i++)
|
||||
intel_region_release(&brw->state.color_regions[i]);
|
||||
intel_region_release(&brw->state.depth_region);
|
||||
|
||||
/* reference new color/depth regions */
|
||||
for (i = 0; i < num_color_regions; i++)
|
||||
intel_region_reference(&brw->state.color_regions[i], color_regions[i]);
|
||||
intel_region_reference(&brw->state.depth_region, depth_region);
|
||||
brw->state.nr_color_regions = num_color_regions;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/**
|
||||
* called from intel_batchbuffer_flush and children before sending a
|
||||
* batchbuffer off.
|
||||
*/
|
||||
static void brw_finish_batch(struct intel_context *intel)
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
brw_emit_query_end(brw);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* called from intelFlushBatchLocked
|
||||
*/
|
||||
static void brw_new_batch( struct intel_context *intel )
|
||||
{
|
||||
struct brw_context *brw = brw_context(&intel->ctx);
|
||||
|
||||
/* Check that we didn't just wrap our batchbuffer at a bad time. */
|
||||
assert(!brw->no_batch_wrap);
|
||||
|
||||
brw->curbe.need_new_bo = GL_TRUE;
|
||||
|
||||
/* Mark all context state as needing to be re-emitted.
|
||||
* This is probably not as severe as on 915, since almost all of our state
|
||||
* is just in referenced buffers.
|
||||
*/
|
||||
brw->state.dirty.brw |= BRW_NEW_CONTEXT;
|
||||
|
||||
brw->state.dirty.mesa |= ~0;
|
||||
brw->state.dirty.brw |= ~0;
|
||||
brw->state.dirty.cache |= ~0;
|
||||
|
||||
/* Move to the end of the current upload buffer so that we'll force choosing
|
||||
* a new buffer next time.
|
||||
*/
|
||||
if (brw->vb.upload.bo != NULL) {
|
||||
dri_bo_unreference(brw->vb.upload.bo);
|
||||
brw->vb.upload.bo = NULL;
|
||||
brw->vb.upload.offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void brw_note_fence( struct intel_context *intel, GLuint fence )
|
||||
{
|
||||
brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE;
|
||||
}
|
||||
|
||||
/* called from intelWaitForIdle() and intelFlush()
|
||||
*
|
||||
* For now, just flush everything. Could be smarter later.
|
||||
*/
|
||||
static GLuint brw_flush_cmd( void )
|
||||
{
|
||||
struct brw_mi_flush flush;
|
||||
flush.opcode = CMD_MI_FLUSH;
|
||||
flush.pad = 0;
|
||||
flush.flags = BRW_FLUSH_STATE_CACHE;
|
||||
return *(GLuint *)&flush;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/* _NEW_BUFFERS */
|
||||
if (IS_965(intel->intelScreen->deviceID) &&
|
||||
!IS_G4X(intel->intelScreen->deviceID)) {
|
||||
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
|
||||
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
|
||||
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
|
||||
|
||||
/* The original gen4 hardware couldn't set up WM surfaces pointing
|
||||
* at an offset within a tile, which can happen when rendering to
|
||||
* anything but the base level of a texture or the +X face/0 depth.
|
||||
* This was fixed with the 4 Series hardware.
|
||||
*
|
||||
* For these original chips, you would have to make the depth and
|
||||
* color destination surfaces include information on the texture
|
||||
* type, LOD, face, and various limits to use them as a destination.
|
||||
* I would have done this, but there's also a nasty requirement that
|
||||
* the depth and the color surfaces all be of the same LOD, which
|
||||
* may be a worse requirement than this alignment. (Also, we may
|
||||
* want to just demote the texture to untiled, instead).
|
||||
*/
|
||||
if (irb->region &&
|
||||
irb->region->tiling != I915_TILING_NONE &&
|
||||
(irb->region->draw_offset & 4095)) {
|
||||
DBG("FALLBACK: non-tile-aligned destination for tiled FBO\n");
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
@@ -59,9 +59,9 @@ static void compile_sf_prog( struct brw_context *brw,
|
||||
brw_init_compile(brw, &c.func);
|
||||
|
||||
c.key = *key;
|
||||
c.nr_attrs = brw_count_bits(c.key.attrs);
|
||||
c.nr_attrs = util_count_bits(c.key.attrs);
|
||||
c.nr_attr_regs = (c.nr_attrs+1)/2;
|
||||
c.nr_setup_attrs = brw_count_bits(c.key.attrs & DO_SETUP_BITS);
|
||||
c.nr_setup_attrs = util_count_bits(c.key.attrs & DO_SETUP_BITS);
|
||||
c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
|
||||
|
||||
c.prog_data.urb_read_length = c.nr_attr_regs;
|
||||
|
||||
@@ -150,7 +150,7 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg ip = brw_ip_reg();
|
||||
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
|
||||
GLuint nr = util_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
|
||||
GLuint jmpi = 1;
|
||||
|
||||
if (!nr)
|
||||
@@ -188,7 +188,7 @@ static void do_flatshade_line( struct brw_sf_compile *c )
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_reg ip = brw_ip_reg();
|
||||
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
|
||||
GLuint nr = util_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
|
||||
GLuint jmpi = 1;
|
||||
|
||||
if (!nr)
|
||||
|
||||
@@ -270,7 +270,7 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits)
|
||||
/***********************************************************************
|
||||
* Emit all state:
|
||||
*/
|
||||
void brw_validate_state( struct brw_context *brw )
|
||||
enum pipe_error brw_validate_state( struct brw_context *brw )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
struct intel_context *intel = &brw->intel;
|
||||
@@ -278,10 +278,6 @@ void brw_validate_state( struct brw_context *brw )
|
||||
GLuint i;
|
||||
|
||||
brw_clear_validated_bos(brw);
|
||||
|
||||
state->mesa |= brw->intel.NewGLState;
|
||||
brw->intel.NewGLState = 0;
|
||||
|
||||
brw_add_validated_bo(brw, intel->batch->buf);
|
||||
|
||||
if (brw->emit_state_always) {
|
||||
@@ -290,36 +286,23 @@ void brw_validate_state( struct brw_context *brw )
|
||||
state->cache |= ~0;
|
||||
}
|
||||
|
||||
if (brw->fragment_program != ctx->FragmentProgram._Current) {
|
||||
brw->fragment_program = ctx->FragmentProgram._Current;
|
||||
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
|
||||
}
|
||||
|
||||
if (brw->vertex_program != ctx->VertexProgram._Current) {
|
||||
brw->vertex_program = ctx->VertexProgram._Current;
|
||||
brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
|
||||
}
|
||||
|
||||
if (state->mesa == 0 &&
|
||||
state->cache == 0 &&
|
||||
state->brw == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
|
||||
brw_clear_batch_cache(brw);
|
||||
|
||||
brw->intel.Fallback = 0;
|
||||
|
||||
/* do prepare stage for all atoms */
|
||||
for (i = 0; i < Elements(atoms); i++) {
|
||||
const struct brw_tracked_state *atom = atoms[i];
|
||||
|
||||
if (brw->intel.Fallback)
|
||||
break;
|
||||
|
||||
if (check_state(state, &atom->dirty)) {
|
||||
if (atom->prepare) {
|
||||
atom->prepare(brw);
|
||||
ret = atom->prepare(brw);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,17 +312,18 @@ void brw_validate_state( struct brw_context *brw )
|
||||
* If this fails, we can experience GPU lock-ups.
|
||||
*/
|
||||
{
|
||||
const struct brw_fragment_program *fp;
|
||||
fp = brw_fragment_program_const(brw->fragment_program);
|
||||
const struct brw_fragment_program *fp = brw->fragment_program;
|
||||
if (fp) {
|
||||
assert((fp->tex_units_used & ctx->Texture._EnabledUnits)
|
||||
== fp->tex_units_used);
|
||||
assert(fp->info.max_sampler <= brw->nr_samplers &&
|
||||
fp->info.max_texture <= brw->nr_textures);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void brw_upload_state(struct brw_context *brw)
|
||||
enum pipe_error brw_upload_state(struct brw_context *brw)
|
||||
{
|
||||
struct brw_state_flags *state = &brw->state.dirty;
|
||||
int i;
|
||||
@@ -356,7 +340,7 @@ void brw_upload_state(struct brw_context *brw)
|
||||
_mesa_memset(&examined, 0, sizeof(examined));
|
||||
prev = *state;
|
||||
|
||||
for (i = 0; i < Elements(atoms); i++) {
|
||||
for (i = 0; i < Elements(atoms); i++) {
|
||||
const struct brw_tracked_state *atom = atoms[i];
|
||||
struct brw_state_flags generated;
|
||||
|
||||
@@ -364,12 +348,11 @@ void brw_upload_state(struct brw_context *brw)
|
||||
atom->dirty.brw ||
|
||||
atom->dirty.cache);
|
||||
|
||||
if (brw->intel.Fallback)
|
||||
break;
|
||||
|
||||
if (check_state(state, &atom->dirty)) {
|
||||
if (atom->emit) {
|
||||
atom->emit( brw );
|
||||
ret = atom->emit( brw );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,12 +371,11 @@ void brw_upload_state(struct brw_context *brw)
|
||||
for (i = 0; i < Elements(atoms); i++) {
|
||||
const struct brw_tracked_state *atom = atoms[i];
|
||||
|
||||
if (brw->intel.Fallback)
|
||||
break;
|
||||
|
||||
if (check_state(state, &atom->dirty)) {
|
||||
if (atom->emit) {
|
||||
atom->emit( brw );
|
||||
ret = atom->emit( brw );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,10 +389,11 @@ void brw_upload_state(struct brw_context *brw)
|
||||
brw_print_dirty_count(mesa_bits, state->mesa);
|
||||
brw_print_dirty_count(brw_bits, state->brw);
|
||||
brw_print_dirty_count(cache_bits, state->cache);
|
||||
fprintf(stderr, "\n");
|
||||
debug_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!brw->intel.Fallback)
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
/* Clear dirty flags:
|
||||
*/
|
||||
memset(state, 0, sizeof(*state));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
|
||||
/* XXX: could split the primitive list to fallback only on the
|
||||
* non-conformant primitives.
|
||||
*/
|
||||
static GLboolean check_fallbacks( struct brw_context *brw,
|
||||
const struct _mesa_prim *prim,
|
||||
GLuint nr_prims )
|
||||
{
|
||||
GLcontext *ctx = &brw->intel.ctx;
|
||||
GLuint i;
|
||||
|
||||
/* If we don't require strict OpenGL conformance, never
|
||||
* use fallbacks. If we're forcing fallbacks, always
|
||||
* use fallfacks.
|
||||
*/
|
||||
if (brw->intel.conformance_mode == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
if (brw->intel.conformance_mode == 2)
|
||||
return GL_TRUE;
|
||||
|
||||
if (ctx->Polygon.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (reduced_prim[prim[i].mode] == GL_TRIANGLES)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* BRW hardware will do AA lines, but they are non-conformant it
|
||||
* seems. TBD whether we keep this fallback:
|
||||
*/
|
||||
if (ctx->Line.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (reduced_prim[prim[i].mode] == GL_LINES)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Stipple -- these fallbacks could be resolved with a little
|
||||
* bit of work?
|
||||
*/
|
||||
if (ctx->Line.StippleFlag) {
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
/* GS doesn't get enough information to know when to reset
|
||||
* the stipple counter?!?
|
||||
*/
|
||||
if (prim[i].mode == GL_LINE_LOOP || prim[i].mode == GL_LINE_STRIP)
|
||||
return GL_TRUE;
|
||||
|
||||
if (prim[i].mode == GL_POLYGON &&
|
||||
(ctx->Polygon.FrontMode == GL_LINE ||
|
||||
ctx->Polygon.BackMode == GL_LINE))
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->Point.SmoothFlag) {
|
||||
for (i = 0; i < nr_prims; i++)
|
||||
if (prim[i].mode == GL_POINTS)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* BRW hardware doesn't handle GL_CLAMP texturing correctly;
|
||||
* brw_wm_sampler_state:translate_wrap_mode() treats GL_CLAMP
|
||||
* as GL_CLAMP_TO_EDGE instead. If we're using GL_CLAMP, and
|
||||
* we want strict conformance, force the fallback.
|
||||
* Right now, we only do this for 2D textures.
|
||||
*/
|
||||
{
|
||||
int u;
|
||||
for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
|
||||
if (texUnit->Enabled) {
|
||||
if (texUnit->Enabled & TEXTURE_1D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_1D_INDEX]->WrapS == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
if (texUnit->Enabled & TEXTURE_2D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapS == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_2D_INDEX]->WrapT == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
if (texUnit->Enabled & TEXTURE_3D_BIT) {
|
||||
if (texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapS == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapT == GL_CLAMP ||
|
||||
texUnit->CurrentTex[TEXTURE_3D_INDEX]->WrapR == GL_CLAMP) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Exceeding hw limits on number of VS inputs?
|
||||
*/
|
||||
if (brw->nr_ve == 0 ||
|
||||
brw->nr_ve >= BRW_VEP_MAX) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Position array with zero stride?
|
||||
*/
|
||||
if (brw->vs[brw->ve[0]]->stride == 0)
|
||||
return TRUE;
|
||||
|
||||
|
||||
|
||||
/* Nothing stopping us from the fast path now */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef BRW_TYPES_H
|
||||
#define BRW_TYPES_H
|
||||
|
||||
typedef GLuint uint32_t;
|
||||
typedef GLubyte uint8_t;
|
||||
typedef GLushort uint16_t;
|
||||
/* no GLenum, translate all away */
|
||||
|
||||
typedef GLboolean uint8_t;
|
||||
|
||||
#endif
|
||||
@@ -35,14 +35,6 @@
|
||||
#include "brw_util.h"
|
||||
#include "brw_defines.h"
|
||||
|
||||
GLuint brw_count_bits( GLuint val )
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; val ; val >>= 1)
|
||||
if (val & 1)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
GLuint brw_translate_blend_equation( GLenum mode )
|
||||
|
||||
@@ -61,9 +61,7 @@ static void do_vs_prog( struct brw_context *brw,
|
||||
}
|
||||
|
||||
if (0)
|
||||
_mesa_print_program(&c.vp->program.Base);
|
||||
|
||||
|
||||
tgsi_dump(&c.vp->tokens, 0);
|
||||
|
||||
/* Emit GEN4 code.
|
||||
*/
|
||||
@@ -96,9 +94,9 @@ static void brw_upload_vs_prog(struct brw_context *brw)
|
||||
* the inputs it asks for, whether they are varying or not.
|
||||
*/
|
||||
key.program_string_id = vp->id;
|
||||
key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
|
||||
key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL ||
|
||||
ctx->Polygon.BackMode != GL_FILL);
|
||||
key.nr_userclip = brw->nr_userclip;
|
||||
key.copy_edgeflag = (brw->rast->fill_ccw != PIPE_POLYGON_MODE_FILL ||
|
||||
brw->rast->fill_cw != PIPE_POLYGON_MODE_FILL);
|
||||
|
||||
/* Make an early check for the key.
|
||||
*/
|
||||
@@ -116,7 +114,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
|
||||
*/
|
||||
const struct brw_tracked_state brw_vs_prog = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_TRANSFORM | _NEW_POLYGON,
|
||||
.mesa = PIPE_NEW_UCP | PIPE_NEW_RAST,
|
||||
.brw = BRW_NEW_VERTEX_PROGRAM,
|
||||
.cache = 0
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "main/macros.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "brw_context.h"
|
||||
#include "brw_vs.h"
|
||||
|
||||
@@ -129,6 +129,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
|
||||
reg++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are no inputs, we'll still be reading one attribute's worth
|
||||
* because it's required -- see urb_read_length setting.
|
||||
*/
|
||||
@@ -226,6 +227,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
|
||||
* vertex urb, so is half the amount:
|
||||
*/
|
||||
c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
|
||||
|
||||
/* Setting this field to 0 leads to undefined behavior according to the
|
||||
* the VS_STATE docs. Our VUEs will always have at least one attribute
|
||||
* sitting in them, even if it's padding.
|
||||
@@ -960,9 +962,6 @@ static void emit_arl( struct brw_vs_compile *c,
|
||||
|
||||
/**
|
||||
* Return the brw reg for the given instruction's src argument.
|
||||
* Will return mangled results for SWZ op. The emit_swz() function
|
||||
* ignores this result and recalculates taking extended swizzles into
|
||||
* account.
|
||||
*/
|
||||
static struct brw_reg get_arg( struct brw_vs_compile *c,
|
||||
const struct prog_instruction *inst,
|
||||
@@ -1024,74 +1023,6 @@ static struct brw_reg get_dst( struct brw_vs_compile *c,
|
||||
}
|
||||
|
||||
|
||||
static void emit_swz( struct brw_vs_compile *c,
|
||||
struct brw_reg dst,
|
||||
const struct prog_instruction *inst)
|
||||
{
|
||||
const GLuint argIndex = 0;
|
||||
const struct prog_src_register src = inst->SrcReg[argIndex];
|
||||
struct brw_compile *p = &c->func;
|
||||
GLuint zeros_mask = 0;
|
||||
GLuint ones_mask = 0;
|
||||
GLuint src_mask = 0;
|
||||
GLubyte src_swz[4];
|
||||
GLboolean need_tmp = (src.Negate &&
|
||||
dst.file != BRW_GENERAL_REGISTER_FILE);
|
||||
struct brw_reg tmp = dst;
|
||||
GLuint i;
|
||||
|
||||
if (need_tmp)
|
||||
tmp = get_tmp(c);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (dst.dw1.bits.writemask & (1<<i)) {
|
||||
GLubyte s = GET_SWZ(src.Swizzle, i);
|
||||
switch (s) {
|
||||
case SWIZZLE_X:
|
||||
case SWIZZLE_Y:
|
||||
case SWIZZLE_Z:
|
||||
case SWIZZLE_W:
|
||||
src_mask |= 1<<i;
|
||||
src_swz[i] = s;
|
||||
break;
|
||||
case SWIZZLE_ZERO:
|
||||
zeros_mask |= 1<<i;
|
||||
break;
|
||||
case SWIZZLE_ONE:
|
||||
ones_mask |= 1<<i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do src first, in case dst aliases src:
|
||||
*/
|
||||
if (src_mask) {
|
||||
struct brw_reg arg0;
|
||||
|
||||
arg0 = get_src_reg(c, inst, argIndex);
|
||||
|
||||
arg0 = brw_swizzle(arg0,
|
||||
src_swz[0], src_swz[1],
|
||||
src_swz[2], src_swz[3]);
|
||||
|
||||
brw_MOV(p, brw_writemask(tmp, src_mask), arg0);
|
||||
}
|
||||
|
||||
if (zeros_mask)
|
||||
brw_MOV(p, brw_writemask(tmp, zeros_mask), brw_imm_f(0));
|
||||
|
||||
if (ones_mask)
|
||||
brw_MOV(p, brw_writemask(tmp, ones_mask), brw_imm_f(1));
|
||||
|
||||
if (src.Negate)
|
||||
brw_MOV(p, brw_writemask(tmp, src.Negate), negate(tmp));
|
||||
|
||||
if (need_tmp) {
|
||||
brw_MOV(p, dst, tmp);
|
||||
release_tmp(c, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -1332,20 +1263,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
|
||||
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||
|
||||
/* Message registers can't be read, so copy the output into GRF register
|
||||
if they are used in source registers */
|
||||
for (insn = 0; insn < nr_insns; insn++) {
|
||||
GLuint i;
|
||||
struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
|
||||
for (i = 0; i < 3; i++) {
|
||||
struct prog_src_register *src = &inst->SrcReg[i];
|
||||
GLuint index = src->Index;
|
||||
GLuint file = src->File;
|
||||
if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
|
||||
c->output_regs[index].used_in_src = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Static register allocation
|
||||
*/
|
||||
brw_vs_alloc_regs(c);
|
||||
@@ -1362,18 +1279,14 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
_mesa_print_instruction(inst);
|
||||
#endif
|
||||
|
||||
/* Get argument regs. SWZ is special and does this itself.
|
||||
/* Get argument regs.
|
||||
*/
|
||||
if (inst->Opcode != OPCODE_SWZ)
|
||||
for (i = 0; i < 3; i++) {
|
||||
const struct prog_src_register *src = &inst->SrcReg[i];
|
||||
index = src->Index;
|
||||
file = src->File;
|
||||
if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
|
||||
args[i] = c->output_regs[index].reg;
|
||||
else
|
||||
args[i] = get_arg(c, inst, i);
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
const struct prog_src_register *src = &inst->SrcReg[i];
|
||||
index = src->Index;
|
||||
file = src->File;
|
||||
args[i] = get_arg(c, inst, i);
|
||||
}
|
||||
|
||||
/* Get dest regs. Note that it is possible for a reg to be both
|
||||
* dst and arg, given the static allocation of registers. So
|
||||
@@ -1381,10 +1294,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
*/
|
||||
index = inst->DstReg.Index;
|
||||
file = inst->DstReg.File;
|
||||
if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
|
||||
dst = c->output_regs[index].reg;
|
||||
else
|
||||
dst = get_dst(c, inst->DstReg);
|
||||
dst = get_dst(c, inst->DstReg);
|
||||
|
||||
if (inst->SaturateMode != SATURATE_OFF) {
|
||||
_mesa_problem(NULL, "Unsupported saturate %d in vertex shader",
|
||||
@@ -1392,151 +1302,144 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
}
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_ABS:
|
||||
case TGSI_OPCODE_ABS:
|
||||
brw_MOV(p, dst, brw_abs(args[0]));
|
||||
break;
|
||||
case OPCODE_ADD:
|
||||
case TGSI_OPCODE_ADD:
|
||||
brw_ADD(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_COS:
|
||||
case TGSI_OPCODE_COS:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_COS, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_DP3:
|
||||
case TGSI_OPCODE_DP3:
|
||||
brw_DP3(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_DP4:
|
||||
case TGSI_OPCODE_DP4:
|
||||
brw_DP4(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_DPH:
|
||||
case TGSI_OPCODE_DPH:
|
||||
brw_DPH(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_NRM3:
|
||||
case TGSI_OPCODE_NRM3:
|
||||
emit_nrm(c, dst, args[0], 3);
|
||||
break;
|
||||
case OPCODE_NRM4:
|
||||
case TGSI_OPCODE_NRM4:
|
||||
emit_nrm(c, dst, args[0], 4);
|
||||
break;
|
||||
case OPCODE_DST:
|
||||
case TGSI_OPCODE_DST:
|
||||
unalias2(c, dst, args[0], args[1], emit_dst_noalias);
|
||||
break;
|
||||
case OPCODE_EXP:
|
||||
case TGSI_OPCODE_EXP:
|
||||
unalias1(c, dst, args[0], emit_exp_noalias);
|
||||
break;
|
||||
case OPCODE_EX2:
|
||||
case TGSI_OPCODE_EX2:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_ARL:
|
||||
case TGSI_OPCODE_ARL:
|
||||
emit_arl(c, dst, args[0]);
|
||||
break;
|
||||
case OPCODE_FLR:
|
||||
case TGSI_OPCODE_FLR:
|
||||
brw_RNDD(p, dst, args[0]);
|
||||
break;
|
||||
case OPCODE_FRC:
|
||||
case TGSI_OPCODE_FRC:
|
||||
brw_FRC(p, dst, args[0]);
|
||||
break;
|
||||
case OPCODE_LOG:
|
||||
case TGSI_OPCODE_LOG:
|
||||
unalias1(c, dst, args[0], emit_log_noalias);
|
||||
break;
|
||||
case OPCODE_LG2:
|
||||
case TGSI_OPCODE_LG2:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_LIT:
|
||||
case TGSI_OPCODE_LIT:
|
||||
unalias1(c, dst, args[0], emit_lit_noalias);
|
||||
break;
|
||||
case OPCODE_LRP:
|
||||
case TGSI_OPCODE_LRP:
|
||||
unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
|
||||
break;
|
||||
case OPCODE_MAD:
|
||||
case TGSI_OPCODE_MAD:
|
||||
brw_MOV(p, brw_acc_reg(), args[2]);
|
||||
brw_MAC(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_MAX:
|
||||
case TGSI_OPCODE_MAX:
|
||||
emit_max(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_MIN:
|
||||
case TGSI_OPCODE_MIN:
|
||||
emit_min(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_MOV:
|
||||
case TGSI_OPCODE_MOV:
|
||||
brw_MOV(p, dst, args[0]);
|
||||
break;
|
||||
case OPCODE_MUL:
|
||||
case TGSI_OPCODE_MUL:
|
||||
brw_MUL(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_POW:
|
||||
case TGSI_OPCODE_POW:
|
||||
emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_RCP:
|
||||
case TGSI_OPCODE_RCP:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_RSQ:
|
||||
case TGSI_OPCODE_RSQ:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
|
||||
case OPCODE_SEQ:
|
||||
case TGSI_OPCODE_SEQ:
|
||||
emit_seq(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SIN:
|
||||
case TGSI_OPCODE_SIN:
|
||||
emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, args[0], BRW_MATH_PRECISION_FULL);
|
||||
break;
|
||||
case OPCODE_SNE:
|
||||
case TGSI_OPCODE_SNE:
|
||||
emit_sne(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SGE:
|
||||
case TGSI_OPCODE_SGE:
|
||||
emit_sge(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SGT:
|
||||
case TGSI_OPCODE_SGT:
|
||||
emit_sgt(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SLT:
|
||||
case TGSI_OPCODE_SLT:
|
||||
emit_slt(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SLE:
|
||||
case TGSI_OPCODE_SLE:
|
||||
emit_sle(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_SUB:
|
||||
case TGSI_OPCODE_SUB:
|
||||
brw_ADD(p, dst, args[0], negate(args[1]));
|
||||
break;
|
||||
case OPCODE_SWZ:
|
||||
/* The args[0] value can't be used here as it won't have
|
||||
* correctly encoded the full swizzle:
|
||||
*/
|
||||
emit_swz(c, dst, inst);
|
||||
break;
|
||||
case OPCODE_TRUNC:
|
||||
case TGSI_OPCODE_TRUNC:
|
||||
/* round toward zero */
|
||||
brw_RNDZ(p, dst, args[0]);
|
||||
break;
|
||||
case OPCODE_XPD:
|
||||
case TGSI_OPCODE_XPD:
|
||||
emit_xpd(p, dst, args[0], args[1]);
|
||||
break;
|
||||
case OPCODE_IF:
|
||||
case TGSI_OPCODE_IF:
|
||||
assert(if_depth < MAX_IF_DEPTH);
|
||||
if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
|
||||
/* Note that brw_IF smashes the predicate_control field. */
|
||||
if_inst[if_depth]->header.predicate_control = get_predicate(inst);
|
||||
if_depth++;
|
||||
break;
|
||||
case OPCODE_ELSE:
|
||||
case TGSI_OPCODE_ELSE:
|
||||
if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
|
||||
break;
|
||||
case OPCODE_ENDIF:
|
||||
case TGSI_OPCODE_ENDIF:
|
||||
assert(if_depth > 0);
|
||||
brw_ENDIF(p, if_inst[--if_depth]);
|
||||
break;
|
||||
case OPCODE_BGNLOOP:
|
||||
case TGSI_OPCODE_BGNLOOP:
|
||||
loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
|
||||
break;
|
||||
case OPCODE_BRK:
|
||||
case TGSI_OPCODE_BRK:
|
||||
brw_set_predicate_control(p, get_predicate(inst));
|
||||
brw_BREAK(p);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
break;
|
||||
case OPCODE_CONT:
|
||||
case TGSI_OPCODE_CONT:
|
||||
brw_set_predicate_control(p, get_predicate(inst));
|
||||
brw_CONT(p);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
break;
|
||||
case OPCODE_ENDLOOP:
|
||||
case TGSI_OPCODE_ENDLOOP:
|
||||
{
|
||||
struct brw_instruction *inst0, *inst1;
|
||||
GLuint br = 1;
|
||||
@@ -1550,23 +1453,23 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
/* patch all the BREAK/CONT instructions from last BEGINLOOP */
|
||||
while (inst0 > loop_inst[loop_depth]) {
|
||||
inst0--;
|
||||
if (inst0->header.opcode == BRW_OPCODE_BREAK) {
|
||||
if (inst0->header.opcode == BRW_TGSI_OPCODE_BREAK) {
|
||||
inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
|
||||
inst0->bits3.if_else.pop_count = 0;
|
||||
}
|
||||
else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
|
||||
else if (inst0->header.opcode == BRW_TGSI_OPCODE_CONTINUE) {
|
||||
inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
|
||||
inst0->bits3.if_else.pop_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPCODE_BRA:
|
||||
case TGSI_OPCODE_BRA:
|
||||
brw_set_predicate_control(p, get_predicate(inst));
|
||||
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
break;
|
||||
case OPCODE_CAL:
|
||||
case TGSI_OPCODE_CAL:
|
||||
brw_set_access_mode(p, BRW_ALIGN_1);
|
||||
brw_ADD(p, deref_1d(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
|
||||
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||
@@ -1575,27 +1478,27 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
brw_save_call(p, inst->Comment, p->nr_insn);
|
||||
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
|
||||
break;
|
||||
case OPCODE_RET:
|
||||
case TGSI_OPCODE_RET:
|
||||
brw_ADD(p, get_addr_reg(stack_index),
|
||||
get_addr_reg(stack_index), brw_imm_d(-4));
|
||||
brw_set_access_mode(p, BRW_ALIGN_1);
|
||||
brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0));
|
||||
brw_set_access_mode(p, BRW_ALIGN_16);
|
||||
break;
|
||||
case OPCODE_END:
|
||||
case TGSI_OPCODE_END:
|
||||
end_offset = p->nr_insn;
|
||||
/* this instruction will get patched later to jump past subroutine
|
||||
* code, etc.
|
||||
*/
|
||||
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
|
||||
break;
|
||||
case OPCODE_PRINT:
|
||||
case TGSI_OPCODE_PRINT:
|
||||
/* no-op */
|
||||
break;
|
||||
case OPCODE_BGNSUB:
|
||||
case TGSI_OPCODE_BGNSUB:
|
||||
brw_save_label(p, inst->Comment, p->nr_insn);
|
||||
break;
|
||||
case OPCODE_ENDSUB:
|
||||
case TGSI_OPCODE_ENDSUB:
|
||||
/* no-op */
|
||||
break;
|
||||
default:
|
||||
@@ -1618,33 +1521,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
|
||||
hw_insn->header.destreg__conditionalmod = BRW_CONDITIONAL_NZ;
|
||||
}
|
||||
|
||||
if ((inst->DstReg.File == PROGRAM_OUTPUT)
|
||||
&& (inst->DstReg.Index != VERT_RESULT_HPOS)
|
||||
&& c->output_regs[inst->DstReg.Index].used_in_src) {
|
||||
brw_MOV(p, get_dst(c, inst->DstReg), dst);
|
||||
}
|
||||
|
||||
/* Result color clamping.
|
||||
*
|
||||
* When destination register is an output register and
|
||||
* it's primary/secondary front/back color, we have to clamp
|
||||
* the result to [0,1]. This is done by enabling the
|
||||
* saturation bit for the last instruction.
|
||||
*
|
||||
* We don't use brw_set_saturate() as it modifies
|
||||
* p->current->header.saturate, which affects all the subsequent
|
||||
* instructions. Instead, we directly modify the header
|
||||
* of the last (already stored) instruction.
|
||||
*/
|
||||
if (inst->DstReg.File == PROGRAM_OUTPUT) {
|
||||
if ((inst->DstReg.Index == VERT_RESULT_COL0)
|
||||
|| (inst->DstReg.Index == VERT_RESULT_COL1)
|
||||
|| (inst->DstReg.Index == VERT_RESULT_BFC0)
|
||||
|| (inst->DstReg.Index == VERT_RESULT_BFC1)) {
|
||||
p->store[p->nr_insn-1].header.saturate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
release_tmps(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,61 +269,46 @@ static void brw_wm_populate_key( struct brw_context *brw,
|
||||
uses_depth,
|
||||
key);
|
||||
|
||||
/* Revisit this, figure out if it's really useful, and either push
|
||||
* it into the state tracker so that everyone benefits (use to
|
||||
* create fs varients with TEX rather than TXP), or discard.
|
||||
*/
|
||||
key->proj_attrib_mask = ~0; /*brw->wm.input_size_masks[4-1];*/
|
||||
|
||||
/* BRW_NEW_WM_INPUT_DIMENSIONS */
|
||||
key->proj_attrib_mask = brw->wm.input_size_masks[4-1];
|
||||
/* PIPE_NEW_RAST */
|
||||
key->flat_shade = brw->rast.flat_shade;
|
||||
|
||||
/* _NEW_LIGHT */
|
||||
key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
|
||||
|
||||
/* _NEW_HINT */
|
||||
key->linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
|
||||
/* This can be determined by looking at the INTERP mode each input decl.
|
||||
*/
|
||||
key->linear_color = 0;
|
||||
|
||||
/* _NEW_TEXTURE */
|
||||
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
|
||||
const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
|
||||
|
||||
if (unit->_ReallyEnabled) {
|
||||
const struct gl_texture_object *t = unit->_Current;
|
||||
const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
|
||||
if (i < brw->nr_textures) {
|
||||
const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
|
||||
const struct gl_texture_object *t = unit->_Current;
|
||||
const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
|
||||
|
||||
if (img->InternalFormat == GL_YCBCR_MESA) {
|
||||
key->yuvtex_mask |= 1 << i;
|
||||
if (img->TexFormat->MesaFormat == MESA_FORMAT_YCBCR)
|
||||
key->yuvtex_swap_mask |= 1 << i;
|
||||
key->yuvtex_swap_mask |= 1 << i;
|
||||
}
|
||||
|
||||
key->tex_swizzles[i] = t->_Swizzle;
|
||||
key->tex_swizzles[i] = t->_Swizzle;
|
||||
|
||||
if (0)
|
||||
key->shadowtex_mask |= 1<<i;
|
||||
}
|
||||
else {
|
||||
key->tex_swizzles[i] = SWIZZLE_NOOP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shadow */
|
||||
key->shadowtex_mask = fp->program.Base.ShadowSamplers;
|
||||
|
||||
/* _NEW_BUFFERS */
|
||||
/*
|
||||
* Include the draw buffer origin and height so that we can calculate
|
||||
* fragment position values relative to the bottom left of the drawable,
|
||||
* from the incoming screen origin relative position we get as part of our
|
||||
* payload.
|
||||
*
|
||||
* We could avoid recompiling by including this as a constant referenced by
|
||||
* our program, but if we were to do that it would also be nice to handle
|
||||
* getting that constant updated at batchbuffer submit time (when we
|
||||
* hold the lock and know where the buffer really is) rather than at emit
|
||||
* time when we don't hold the lock and are just guessing. We could also
|
||||
* just avoid using this as key data if the program doesn't use
|
||||
* fragment.position.
|
||||
*
|
||||
* This pretty much becomes moot with DRI2 and redirected buffers anyway,
|
||||
* as our origins will always be zero then.
|
||||
*/
|
||||
/* _NEW_FRAMEBUFFER */
|
||||
if (brw->intel.driDrawable != NULL) {
|
||||
key->origin_x = brw->intel.driDrawable->x;
|
||||
key->origin_y = brw->intel.driDrawable->y;
|
||||
key->drawable_height = brw->intel.driDrawable->h;
|
||||
key->drawable_height = brw->fb.cbufs[0].height;
|
||||
}
|
||||
|
||||
/* CACHE_NEW_VS_PROG */
|
||||
|
||||
@@ -76,7 +76,6 @@ struct brw_wm_prog_key {
|
||||
GLuint tex_swizzles[BRW_MAX_TEX_UNIT];
|
||||
|
||||
GLuint program_string_id:32;
|
||||
GLuint origin_x, origin_y;
|
||||
GLuint drawable_height;
|
||||
GLuint vp_outputs_written;
|
||||
};
|
||||
|
||||
@@ -125,23 +125,21 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
|
||||
{
|
||||
struct brw_compile *p = &c->func;
|
||||
|
||||
/* Calculate the pixel offset from window bottom left into destination
|
||||
* X and Y channels.
|
||||
*/
|
||||
if (mask & WRITEMASK_X) {
|
||||
/* X' = X - origin */
|
||||
brw_ADD(p,
|
||||
/* X' = X */
|
||||
brw_MOV(p,
|
||||
dst[0],
|
||||
retype(arg0[0], BRW_REGISTER_TYPE_W),
|
||||
brw_imm_d(0 - c->key.origin_x));
|
||||
retype(arg0[0], BRW_REGISTER_TYPE_W));
|
||||
}
|
||||
|
||||
/* XXX: is this needed any more, or is this a NOOP?
|
||||
*/
|
||||
if (mask & WRITEMASK_Y) {
|
||||
/* Y' = height - (Y - origin_y) = height + origin_y - Y */
|
||||
/* Y' = height - 1 - Y */
|
||||
brw_ADD(p,
|
||||
dst[1],
|
||||
negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
|
||||
brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));
|
||||
brw_imm_d(c->key.drawable_height - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,7 +1374,6 @@ void brw_wm_emit( struct brw_wm_compile *c )
|
||||
break;
|
||||
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_SWZ:
|
||||
emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
|
||||
break;
|
||||
|
||||
|
||||
@@ -30,25 +30,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "main/glheader.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/enums.h"
|
||||
#include "pipe/p_shader_constants.h"
|
||||
|
||||
#include "brw_context.h"
|
||||
#include "brw_wm.h"
|
||||
#include "brw_util.h"
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "shader/prog_statevars.h"
|
||||
|
||||
|
||||
/** An invalid texture target */
|
||||
#define TEX_TARGET_NONE NUM_TEXTURE_TARGETS
|
||||
|
||||
/** An invalid texture unit */
|
||||
#define TEX_UNIT_NONE BRW_MAX_TEX_UNIT
|
||||
|
||||
#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
|
||||
|
||||
#define X 0
|
||||
#define Y 1
|
||||
@@ -68,11 +55,6 @@ static const char *wm_opcode_strings[] = {
|
||||
"FRONTFACING",
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const char *wm_file_strings[] = {
|
||||
"PAYLOAD"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@@ -165,13 +147,13 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c )
|
||||
}
|
||||
|
||||
c->fp_temp |= 1<<(bit-1);
|
||||
return dst_reg(PROGRAM_TEMPORARY, FIRST_INTERNAL_TEMP+(bit-1));
|
||||
return dst_reg(PROGRAM_TEMPORARY, c->first_internal_temp+(bit-1));
|
||||
}
|
||||
|
||||
|
||||
static void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )
|
||||
{
|
||||
c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));
|
||||
c->fp_temp &= ~(1 << (temp.Index - c->first_internal_temp));
|
||||
}
|
||||
|
||||
|
||||
@@ -192,58 +174,29 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
|
||||
return inst;
|
||||
}
|
||||
|
||||
static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
|
||||
GLuint op,
|
||||
struct prog_dst_register dest,
|
||||
GLuint saturate,
|
||||
GLuint tex_src_unit,
|
||||
GLuint tex_src_target,
|
||||
GLuint tex_shadow,
|
||||
struct prog_src_register src0,
|
||||
struct prog_src_register src1,
|
||||
struct prog_src_register src2 )
|
||||
static struct prog_instruction * emit_op(struct brw_wm_compile *c,
|
||||
GLuint op,
|
||||
struct prog_dst_register dest,
|
||||
GLuint saturate,
|
||||
struct prog_src_register src0,
|
||||
struct prog_src_register src1,
|
||||
struct prog_src_register src2 )
|
||||
{
|
||||
struct prog_instruction *inst = get_fp_inst(c);
|
||||
|
||||
assert(tex_src_unit < BRW_MAX_TEX_UNIT ||
|
||||
tex_src_unit == TEX_UNIT_NONE);
|
||||
assert(tex_src_target < NUM_TEXTURE_TARGETS ||
|
||||
tex_src_target == TEX_TARGET_NONE);
|
||||
|
||||
/* update mask of which texture units are referenced by this program */
|
||||
if (tex_src_unit != TEX_UNIT_NONE)
|
||||
c->fp->tex_units_used |= (1 << tex_src_unit);
|
||||
|
||||
memset(inst, 0, sizeof(*inst));
|
||||
|
||||
inst->Opcode = op;
|
||||
inst->DstReg = dest;
|
||||
inst->SaturateMode = saturate;
|
||||
inst->TexSrcUnit = tex_src_unit;
|
||||
inst->TexSrcTarget = tex_src_target;
|
||||
inst->TexShadow = tex_shadow;
|
||||
inst->SrcReg[0] = src0;
|
||||
inst->SrcReg[1] = src1;
|
||||
inst->SrcReg[2] = src2;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
static struct prog_instruction * emit_op(struct brw_wm_compile *c,
|
||||
GLuint op,
|
||||
struct prog_dst_register dest,
|
||||
GLuint saturate,
|
||||
struct prog_src_register src0,
|
||||
struct prog_src_register src1,
|
||||
struct prog_src_register src2 )
|
||||
{
|
||||
return emit_tex_op(c, op, dest, saturate,
|
||||
TEX_UNIT_NONE, TEX_TARGET_NONE, 0, /* unit, tgt, shadow */
|
||||
src0, src1, src2);
|
||||
}
|
||||
|
||||
|
||||
/* Many Mesa opcodes produce the same value across all the result channels.
|
||||
/* Many opcodes produce the same value across all the result channels.
|
||||
* We'd rather not have to support that splatting in the opcode implementations,
|
||||
* and brw_wm_pass*.c wants to optimize them out by shuffling references around
|
||||
* anyway. We can easily get both by emitting the opcode to one channel, and
|
||||
@@ -267,7 +220,7 @@ static struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
|
||||
other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
|
||||
if (other_channel_mask != 0) {
|
||||
inst = emit_op(c,
|
||||
OPCODE_MOV,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(inst0->DstReg, other_channel_mask),
|
||||
0,
|
||||
src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
|
||||
@@ -356,7 +309,9 @@ static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
|
||||
}
|
||||
|
||||
static void emit_interp( struct brw_wm_compile *c,
|
||||
GLuint idx )
|
||||
GLuint semantic,
|
||||
GLuint semantic_index,
|
||||
GLuint interp_mode )
|
||||
{
|
||||
struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
|
||||
struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
|
||||
@@ -366,7 +321,7 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
* multiplied by 1/W in the SF program, and LINTERP on those
|
||||
* which have not:
|
||||
*/
|
||||
switch (idx) {
|
||||
switch (semantic) {
|
||||
case FRAG_ATTRIB_WPOS:
|
||||
/* Have to treat wpos.xy specially:
|
||||
*/
|
||||
@@ -390,8 +345,8 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
deltas,
|
||||
src_undef());
|
||||
break;
|
||||
case FRAG_ATTRIB_COL0:
|
||||
case FRAG_ATTRIB_COL1:
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
if (c->key.flat_shade) {
|
||||
emit_op(c,
|
||||
WM_CINTERP,
|
||||
@@ -402,25 +357,13 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
src_undef());
|
||||
}
|
||||
else {
|
||||
if (c->key.linear_color) {
|
||||
emit_op(c,
|
||||
WM_LINTERP,
|
||||
dst,
|
||||
0,
|
||||
interp,
|
||||
deltas,
|
||||
src_undef());
|
||||
}
|
||||
else {
|
||||
/* perspective-corrected color interpolation */
|
||||
emit_op(c,
|
||||
WM_PINTERP,
|
||||
dst,
|
||||
0,
|
||||
interp,
|
||||
deltas,
|
||||
get_pixel_w(c));
|
||||
}
|
||||
emit_op(c,
|
||||
translate_interp_mode(interp_mode),
|
||||
dst,
|
||||
0,
|
||||
interp,
|
||||
deltas,
|
||||
src_undef());
|
||||
}
|
||||
break;
|
||||
case FRAG_ATTRIB_FOGC:
|
||||
@@ -434,7 +377,7 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
get_pixel_w(c));
|
||||
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_YZW),
|
||||
0,
|
||||
src_swizzle(interp,
|
||||
@@ -468,7 +411,7 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
get_pixel_w(c));
|
||||
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_ZW),
|
||||
0,
|
||||
src_swizzle(interp,
|
||||
@@ -482,7 +425,7 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
|
||||
default:
|
||||
emit_op(c,
|
||||
WM_PINTERP,
|
||||
translate_interp_mode(interp_mode),
|
||||
dst,
|
||||
0,
|
||||
interp,
|
||||
@@ -490,8 +433,6 @@ static void emit_interp( struct brw_wm_compile *c,
|
||||
get_pixel_w(c));
|
||||
break;
|
||||
}
|
||||
|
||||
c->fp_interp_emitted |= 1<<idx;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -581,7 +522,7 @@ static void precalc_dst( struct brw_wm_compile *c,
|
||||
/* dst.y = mul src0.y, src1.y
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_MUL,
|
||||
TGSI_OPCODE_MUL,
|
||||
dst_mask(dst, WRITEMASK_Y),
|
||||
inst->SaturateMode,
|
||||
src0,
|
||||
@@ -596,7 +537,7 @@ static void precalc_dst( struct brw_wm_compile *c,
|
||||
/* dst.xz = swz src0.1zzz
|
||||
*/
|
||||
swz = emit_op(c,
|
||||
OPCODE_SWZ,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_XZ),
|
||||
inst->SaturateMode,
|
||||
src_swizzle(src0, SWIZZLE_ONE, z, z, z),
|
||||
@@ -609,7 +550,7 @@ static void precalc_dst( struct brw_wm_compile *c,
|
||||
/* dst.w = mov src1.w
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_W),
|
||||
inst->SaturateMode,
|
||||
src1,
|
||||
@@ -631,7 +572,7 @@ static void precalc_lit( struct brw_wm_compile *c,
|
||||
/* dst.xw = swz src0.1111
|
||||
*/
|
||||
swz = emit_op(c,
|
||||
OPCODE_SWZ,
|
||||
TGSI_OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_XW),
|
||||
0,
|
||||
src_swizzle1(src0, SWIZZLE_ONE),
|
||||
@@ -643,7 +584,7 @@ static void precalc_lit( struct brw_wm_compile *c,
|
||||
|
||||
if (dst.WriteMask & WRITEMASK_YZ) {
|
||||
emit_op(c,
|
||||
OPCODE_LIT,
|
||||
TGSI_OPCODE_LIT,
|
||||
dst_mask(dst, WRITEMASK_YZ),
|
||||
inst->SaturateMode,
|
||||
src0,
|
||||
@@ -681,7 +622,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
coord = src_reg_from_dst(tmpcoord);
|
||||
|
||||
/* tmpcoord = src0 (i.e.: coord = src0) */
|
||||
out = emit_op(c, OPCODE_MOV,
|
||||
out = emit_op(c, TGSI_OPCODE_MOV,
|
||||
tmpcoord,
|
||||
0,
|
||||
src0,
|
||||
@@ -691,7 +632,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
out->SrcReg[0].Abs = 1;
|
||||
|
||||
/* tmp0 = MAX(coord.X, coord.Y) */
|
||||
emit_op(c, OPCODE_MAX,
|
||||
emit_op(c, TGSI_OPCODE_MAX,
|
||||
tmp0,
|
||||
0,
|
||||
src_swizzle1(coord, X),
|
||||
@@ -699,7 +640,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
src_undef());
|
||||
|
||||
/* tmp1 = MAX(tmp0, coord.Z) */
|
||||
emit_op(c, OPCODE_MAX,
|
||||
emit_op(c, TGSI_OPCODE_MAX,
|
||||
tmp1,
|
||||
0,
|
||||
tmp0src,
|
||||
@@ -707,7 +648,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
src_undef());
|
||||
|
||||
/* tmp0 = 1 / tmp1 */
|
||||
emit_op(c, OPCODE_RCP,
|
||||
emit_op(c, TGSI_OPCODE_RCP,
|
||||
dst_mask(tmp0, WRITEMASK_X),
|
||||
0,
|
||||
tmp1src,
|
||||
@@ -715,7 +656,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
src_undef());
|
||||
|
||||
/* tmpCoord = src0 * tmp0 */
|
||||
emit_op(c, OPCODE_MUL,
|
||||
emit_op(c, TGSI_OPCODE_MUL,
|
||||
tmpcoord,
|
||||
0,
|
||||
src0,
|
||||
@@ -738,7 +679,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
/* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height }
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_MUL,
|
||||
TGSI_OPCODE_MUL,
|
||||
tmpcoord,
|
||||
0,
|
||||
inst->SrcReg[0],
|
||||
@@ -785,7 +726,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
/* tmp = TEX ...
|
||||
*/
|
||||
emit_tex_op(c,
|
||||
OPCODE_TEX,
|
||||
TGSI_OPCODE_TEX,
|
||||
tmp,
|
||||
inst->SaturateMode,
|
||||
unit,
|
||||
@@ -798,7 +739,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
/* tmp.xyz = ADD TMP, C0
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_ADD,
|
||||
TGSI_OPCODE_ADD,
|
||||
dst_mask(tmp, WRITEMASK_XYZ),
|
||||
0,
|
||||
tmpsrc,
|
||||
@@ -809,7 +750,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
*/
|
||||
|
||||
emit_op(c,
|
||||
OPCODE_MUL,
|
||||
TGSI_OPCODE_MUL,
|
||||
dst_mask(tmp, WRITEMASK_Y),
|
||||
0,
|
||||
tmpsrc,
|
||||
@@ -824,7 +765,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
*/
|
||||
|
||||
emit_op(c,
|
||||
OPCODE_MAD,
|
||||
TGSI_OPCODE_MAD,
|
||||
dst_mask(dst, WRITEMASK_XYZ),
|
||||
0,
|
||||
swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
|
||||
@@ -834,7 +775,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
/* RGB.y = MAD YUV.z, C1.w, RGB.y
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_MAD,
|
||||
TGSI_OPCODE_MAD,
|
||||
dst_mask(dst, WRITEMASK_Y),
|
||||
0,
|
||||
src_swizzle1(tmpsrc, Z),
|
||||
@@ -846,7 +787,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
else {
|
||||
/* ordinary RGBA tex instruction */
|
||||
emit_tex_op(c,
|
||||
OPCODE_TEX,
|
||||
TGSI_OPCODE_TEX,
|
||||
inst->DstReg,
|
||||
inst->SaturateMode,
|
||||
unit,
|
||||
@@ -861,7 +802,7 @@ static void precalc_tex( struct brw_wm_compile *c,
|
||||
if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
|
||||
/* swizzle the result of the TEX instruction */
|
||||
struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
|
||||
emit_op(c, OPCODE_SWZ,
|
||||
emit_op(c, TGSI_OPCODE_MOV,
|
||||
inst->DstReg,
|
||||
SATURATE_OFF, /* saturate already done above */
|
||||
src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
|
||||
@@ -884,7 +825,7 @@ static GLboolean projtex( struct brw_wm_compile *c,
|
||||
const struct prog_src_register src = inst->SrcReg[0];
|
||||
GLboolean retVal;
|
||||
|
||||
assert(inst->Opcode == OPCODE_TXP);
|
||||
assert(inst->Opcode == TGSI_OPCODE_TXP);
|
||||
|
||||
/* Only try to detect the simplest cases. Could detect (later)
|
||||
* cases where we are trying to emit code like RCP {1.0}, MUL x,
|
||||
@@ -921,7 +862,7 @@ static void precalc_txp( struct brw_wm_compile *c,
|
||||
/* tmp0.w = RCP inst.arg[0][3]
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_RCP,
|
||||
TGSI_OPCODE_RCP,
|
||||
dst_mask(tmp, WRITEMASK_W),
|
||||
0,
|
||||
src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
|
||||
@@ -931,7 +872,7 @@ static void precalc_txp( struct brw_wm_compile *c,
|
||||
/* tmp0.xyz = MUL inst.arg[0], tmp0.wwww
|
||||
*/
|
||||
emit_op(c,
|
||||
OPCODE_MUL,
|
||||
TGSI_OPCODE_MUL,
|
||||
dst_mask(tmp, WRITEMASK_XYZ),
|
||||
0,
|
||||
src0,
|
||||
@@ -1015,6 +956,7 @@ static void validate_src_regs( struct brw_wm_compile *c,
|
||||
GLuint idx = inst->SrcReg[i].Index;
|
||||
if (!(c->fp_interp_emitted & (1<<idx))) {
|
||||
emit_interp(c, idx);
|
||||
c->fp_interp_emitted |= 1<<idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1094,71 +1036,64 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
|
||||
*/
|
||||
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_SWZ:
|
||||
case TGSI_OPCODE_ABS:
|
||||
out = emit_insn(c, inst);
|
||||
out->Opcode = OPCODE_MOV;
|
||||
break;
|
||||
|
||||
case OPCODE_ABS:
|
||||
out = emit_insn(c, inst);
|
||||
out->Opcode = OPCODE_MOV;
|
||||
out->Opcode = TGSI_OPCODE_MOV;
|
||||
out->SrcReg[0].Negate = NEGATE_NONE;
|
||||
out->SrcReg[0].Abs = 1;
|
||||
break;
|
||||
|
||||
case OPCODE_SUB:
|
||||
case TGSI_OPCODE_SUB:
|
||||
out = emit_insn(c, inst);
|
||||
out->Opcode = OPCODE_ADD;
|
||||
out->Opcode = TGSI_OPCODE_ADD;
|
||||
out->SrcReg[1].Negate ^= NEGATE_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_SCS:
|
||||
case TGSI_OPCODE_SCS:
|
||||
out = emit_insn(c, inst);
|
||||
/* This should probably be done in the parser.
|
||||
*/
|
||||
out->DstReg.WriteMask &= WRITEMASK_XY;
|
||||
break;
|
||||
|
||||
case OPCODE_DST:
|
||||
case TGSI_OPCODE_DST:
|
||||
precalc_dst(c, inst);
|
||||
break;
|
||||
|
||||
case OPCODE_LIT:
|
||||
case TGSI_OPCODE_LIT:
|
||||
precalc_lit(c, inst);
|
||||
break;
|
||||
|
||||
case OPCODE_TEX:
|
||||
case TGSI_OPCODE_TEX:
|
||||
precalc_tex(c, inst);
|
||||
break;
|
||||
|
||||
case OPCODE_TXP:
|
||||
case TGSI_OPCODE_TXP:
|
||||
precalc_txp(c, inst);
|
||||
break;
|
||||
|
||||
case OPCODE_TXB:
|
||||
case TGSI_OPCODE_TXB:
|
||||
out = emit_insn(c, inst);
|
||||
out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
|
||||
assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
|
||||
break;
|
||||
|
||||
case OPCODE_XPD:
|
||||
case TGSI_OPCODE_XPD:
|
||||
out = emit_insn(c, inst);
|
||||
/* This should probably be done in the parser.
|
||||
*/
|
||||
out->DstReg.WriteMask &= WRITEMASK_XYZ;
|
||||
break;
|
||||
|
||||
case OPCODE_KIL:
|
||||
case TGSI_OPCODE_KIL:
|
||||
out = emit_insn(c, inst);
|
||||
/* This should probably be done in the parser.
|
||||
*/
|
||||
out->DstReg.WriteMask = 0;
|
||||
break;
|
||||
case OPCODE_END:
|
||||
case TGSI_OPCODE_END:
|
||||
emit_fb_write(c);
|
||||
break;
|
||||
case OPCODE_PRINT:
|
||||
break;
|
||||
default:
|
||||
if (brw_wm_is_scalar_result(inst->Opcode))
|
||||
emit_scalar_insn(c, inst);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -422,7 +422,6 @@ void brw_wm_pass0( struct brw_wm_compile *c )
|
||||
*/
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_SWZ:
|
||||
if (!inst->SaturateMode) {
|
||||
pass0_precalc_mov(c, inst);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
GLuint writemask;
|
||||
GLuint read0, read1, read2;
|
||||
|
||||
if (inst->opcode == OPCODE_KIL) {
|
||||
if (inst->opcode == TGSI_OPCODE_KIL) {
|
||||
track_arg(c, inst, 0, WRITEMASK_XYZW); /* All args contribute to final */
|
||||
continue;
|
||||
}
|
||||
@@ -154,76 +154,75 @@ void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
/* Mark all inputs which contribute to the marked outputs:
|
||||
*/
|
||||
switch (inst->opcode) {
|
||||
case OPCODE_ABS:
|
||||
case OPCODE_FLR:
|
||||
case OPCODE_FRC:
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_SWZ:
|
||||
case OPCODE_TRUNC:
|
||||
case TGSI_OPCODE_ABS:
|
||||
case TGSI_OPCODE_FLR:
|
||||
case TGSI_OPCODE_FRC:
|
||||
case TGSI_OPCODE_MOV:
|
||||
case TGSI_OPCODE_TRUNC:
|
||||
read0 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_SUB:
|
||||
case OPCODE_SLT:
|
||||
case OPCODE_SLE:
|
||||
case OPCODE_SGE:
|
||||
case OPCODE_SGT:
|
||||
case OPCODE_SEQ:
|
||||
case OPCODE_SNE:
|
||||
case OPCODE_ADD:
|
||||
case OPCODE_MAX:
|
||||
case OPCODE_MIN:
|
||||
case OPCODE_MUL:
|
||||
case TGSI_OPCODE_SUB:
|
||||
case TGSI_OPCODE_SLT:
|
||||
case TGSI_OPCODE_SLE:
|
||||
case TGSI_OPCODE_SGE:
|
||||
case TGSI_OPCODE_SGT:
|
||||
case TGSI_OPCODE_SEQ:
|
||||
case TGSI_OPCODE_SNE:
|
||||
case TGSI_OPCODE_ADD:
|
||||
case TGSI_OPCODE_MAX:
|
||||
case TGSI_OPCODE_MIN:
|
||||
case TGSI_OPCODE_MUL:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_DDX:
|
||||
case OPCODE_DDY:
|
||||
case TGSI_OPCODE_DDX:
|
||||
case TGSI_OPCODE_DDY:
|
||||
read0 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_MAD:
|
||||
case OPCODE_CMP:
|
||||
case OPCODE_LRP:
|
||||
case TGSI_OPCODE_MAD:
|
||||
case TGSI_OPCODE_CMP:
|
||||
case TGSI_OPCODE_LRP:
|
||||
read0 = writemask;
|
||||
read1 = writemask;
|
||||
read2 = writemask;
|
||||
break;
|
||||
|
||||
case OPCODE_XPD:
|
||||
case TGSI_OPCODE_XPD:
|
||||
if (writemask & WRITEMASK_X) read0 |= WRITEMASK_YZ;
|
||||
if (writemask & WRITEMASK_Y) read0 |= WRITEMASK_XZ;
|
||||
if (writemask & WRITEMASK_Z) read0 |= WRITEMASK_XY;
|
||||
read1 = read0;
|
||||
break;
|
||||
|
||||
case OPCODE_COS:
|
||||
case OPCODE_EX2:
|
||||
case OPCODE_LG2:
|
||||
case OPCODE_RCP:
|
||||
case OPCODE_RSQ:
|
||||
case OPCODE_SIN:
|
||||
case OPCODE_SCS:
|
||||
case TGSI_OPCODE_COS:
|
||||
case TGSI_OPCODE_EX2:
|
||||
case TGSI_OPCODE_LG2:
|
||||
case TGSI_OPCODE_RCP:
|
||||
case TGSI_OPCODE_RSQ:
|
||||
case TGSI_OPCODE_SIN:
|
||||
case TGSI_OPCODE_SCS:
|
||||
case WM_CINTERP:
|
||||
case WM_PIXELXY:
|
||||
read0 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_POW:
|
||||
case TGSI_OPCODE_POW:
|
||||
read0 = WRITEMASK_X;
|
||||
read1 = WRITEMASK_X;
|
||||
break;
|
||||
|
||||
case OPCODE_TEX:
|
||||
case OPCODE_TXP:
|
||||
case TGSI_OPCODE_TEX:
|
||||
case TGSI_OPCODE_TXP:
|
||||
read0 = get_texcoord_mask(inst->tex_idx);
|
||||
|
||||
if (inst->tex_shadow)
|
||||
read0 |= WRITEMASK_Z;
|
||||
break;
|
||||
|
||||
case OPCODE_TXB:
|
||||
case TGSI_OPCODE_TXB:
|
||||
/* Shadow ignored for txb.
|
||||
*/
|
||||
read0 = get_texcoord_mask(inst->tex_idx) | WRITEMASK_W;
|
||||
@@ -254,28 +253,28 @@ void brw_wm_pass1( struct brw_wm_compile *c )
|
||||
read2 = WRITEMASK_W; /* pixel w */
|
||||
break;
|
||||
|
||||
case OPCODE_DP3:
|
||||
case TGSI_OPCODE_DP3:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZ;
|
||||
break;
|
||||
|
||||
case OPCODE_DPH:
|
||||
case TGSI_OPCODE_DPH:
|
||||
read0 = WRITEMASK_XYZ;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_DP4:
|
||||
case TGSI_OPCODE_DP4:
|
||||
read0 = WRITEMASK_XYZW;
|
||||
read1 = WRITEMASK_XYZW;
|
||||
break;
|
||||
|
||||
case OPCODE_LIT:
|
||||
case TGSI_OPCODE_LIT:
|
||||
read0 = WRITEMASK_XYW;
|
||||
break;
|
||||
|
||||
case OPCODE_DST:
|
||||
case TGSI_OPCODE_DST:
|
||||
case WM_FRONTFACING:
|
||||
case OPCODE_KIL_NV:
|
||||
case TGSI_OPCODE_KIL_NV:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
#define PCI_CHIP_Q45_G 0x2E12
|
||||
#define PCI_CHIP_G45_G 0x2E22
|
||||
#define PCI_CHIP_G41_G 0x2E32
|
||||
#define PCI_CHIP_B43_G 0x2E42
|
||||
|
||||
#define PCI_CHIP_ILD_G 0x0042
|
||||
#define PCI_CHIP_ILM_G 0x0046
|
||||
@@ -84,8 +83,7 @@
|
||||
#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \
|
||||
devid == PCI_CHIP_Q45_G || \
|
||||
devid == PCI_CHIP_G45_G || \
|
||||
devid == PCI_CHIP_G41_G || \
|
||||
devid == PCI_CHIP_B43_G)
|
||||
devid == PCI_CHIP_G41_G)
|
||||
#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM)
|
||||
#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user