i965: Start adding support for the Sandybridge CC unit.

This commit is contained in:
Eric Anholt 2010-01-29 11:18:26 -08:00
parent 9dce60f35b
commit 7ee590424c
9 changed files with 592 additions and 5 deletions

View file

@ -84,7 +84,9 @@ DRIVER_SOURCES = \
brw_wm_pass2.c \
brw_wm_sampler_state.c \
brw_wm_state.c \
brw_wm_surface_state.c
brw_wm_surface_state.c \
gen6_cc.c \
gen6_depthstencil.c
C_SOURCES = \
$(COMMON_SOURCES) \

View file

@ -282,6 +282,9 @@ struct brw_vs_ouput_sizes {
enum brw_cache_id {
BRW_BLEND_STATE,
BRW_DEPTH_STENCIL_STATE,
BRW_COLOR_CALC_STATE,
BRW_CC_VP,
BRW_CC_UNIT,
BRW_WM_PROG,
@ -354,6 +357,9 @@ struct brw_tracked_state {
/* Flags for brw->state.cache.
*/
#define CACHE_NEW_BLEND_STATE (1<<BRW_BLEND_STATE)
#define CACHE_NEW_DEPTH_STENCIL_STATE (1<<BRW_DEPTH_STENCIL_STATE)
#define CACHE_NEW_COLOR_CALC_STATE (1<<BRW_COLOR_CALC_STATE)
#define CACHE_NEW_CC_VP (1<<BRW_CC_VP)
#define CACHE_NEW_CC_UNIT (1<<BRW_CC_UNIT)
#define CACHE_NEW_WM_PROG (1<<BRW_WM_PROG)
@ -643,9 +649,16 @@ struct brw_context
struct {
/* gen4 */
dri_bo *prog_bo;
dri_bo *state_bo;
dri_bo *vp_bo;
/* gen6 */
dri_bo *blend_state_bo;
dri_bo *depth_stencil_state_bo;
dri_bo *color_calc_state_bo;
dri_bo *state_bo;
} cc;
struct {

View file

@ -807,6 +807,7 @@
# define BRW_VE1_COMPONENT_3_SHIFT 16
# define BRW_VE1_DST_OFFSET_SHIFT 0
#define CMD_3D_CC_STATE_POINTERS 0x780e /* GEN6+ */
#define CMD_INDEX_BUFFER 0x780a
#define CMD_VF_STATISTICS_965 0x780b
#define CMD_VF_STATISTICS_GM45 0x680b

View file

@ -91,6 +91,10 @@ const struct brw_tracked_state brw_indices;
const struct brw_tracked_state brw_vertices;
const struct brw_tracked_state brw_index_buffer;
const struct brw_tracked_state gen6_binding_table_pointers;
const struct brw_tracked_state gen6_blend_state;
const struct brw_tracked_state gen6_cc_state_pointers;
const struct brw_tracked_state gen6_color_calc_state;
const struct brw_tracked_state gen6_depth_stencil_state;
/**
* Use same key for WM and VS surfaces.

View file

@ -390,6 +390,7 @@ brw_init_non_surface_cache(struct brw_context *brw)
brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
}

View file

@ -122,9 +122,13 @@ const struct brw_tracked_state *gen6_atoms[] =
&brw_recalculate_urb_fence,
&brw_cc_vp,
&brw_cc_unit,
#endif
&gen6_blend_state, /* must do before cc unit */
&gen6_color_calc_state, /* must do before cc unit */
&gen6_depth_stencil_state, /* must do before cc unit */
&gen6_cc_state_pointers,
&brw_vs_surfaces, /* must do before unit */
&brw_wm_constant_surface, /* must do before wm surfaces/bind bo */
&brw_wm_surfaces, /* must do before samplers and unit */
@ -282,6 +286,7 @@ static struct dirty_bit_map brw_bits[] = {
};
static struct dirty_bit_map cache_bits[] = {
DEFINE_BIT(CACHE_NEW_BLEND_STATE),
DEFINE_BIT(CACHE_NEW_CC_VP),
DEFINE_BIT(CACHE_NEW_CC_UNIT),
DEFINE_BIT(CACHE_NEW_WM_PROG),

View file

@ -658,7 +658,105 @@ struct brw_clip_unit_state
GLfloat viewport_ymax;
};
struct gen6_blend_state
{
struct {
GLuint dest_blend_factor:5;
GLuint source_blend_factor:5;
GLuint pad3:1;
GLuint blend_func:3;
GLuint pad2:1;
GLuint ia_dest_blend_factor:5;
GLuint ia_source_blend_factor:5;
GLuint pad1:1;
GLuint ia_blend_func:3;
GLuint pad0:1;
GLuint ia_blend_enable:1;
GLuint blend_enable:1;
} blend0;
struct {
GLuint post_blend_clamp_enable:1;
GLuint pre_blend_clamp_enable:1;
GLuint clamp_range:2;
GLuint pad0:4;
GLuint x_dither_offset:2;
GLuint y_dither_offset:2;
GLuint dither_enable:1;
GLuint alpha_test_func:3;
GLuint alpha_test_enable:1;
GLuint pad1:1;
GLuint logic_op_func:4;
GLuint logic_op_enable:1;
GLuint pad2:1;
GLuint write_disable_b:1;
GLuint write_disable_g:1;
GLuint write_disable_r:1;
GLuint write_disable_a:1;
GLuint pad3:1;
GLuint alpha_to_coverage_dither:1;
GLuint alpha_to_one:1;
GLuint alpha_to_coverage:1;
} blend1;
};
struct gen6_color_calc_state
{
struct {
GLuint alpha_test_format:1;
GLuint pad0:14;
GLuint round_disable:1;
GLuint bf_stencil_ref:8;
GLuint stencil_ref:8;
} cc0;
union {
GLfloat alpha_ref_f;
struct {
GLuint ui:8;
GLuint pad0:24;
} alpha_ref_fi;
} cc1;
GLfloat constant_r;
GLfloat constant_g;
GLfloat constant_b;
GLfloat constant_a;
};
struct gen6_depth_stencil_state
{
struct {
GLuint pad0:3;
GLuint bf_stencil_pass_depth_pass_op:3;
GLuint bf_stencil_pass_depth_fail_op:3;
GLuint bf_stencil_fail_op:3;
GLuint bf_stencil_func:3;
GLuint bf_stencil_enable:1;
GLuint pad1:2;
GLuint stencil_write_enable:1;
GLuint stencil_pass_depth_pass_op:3;
GLuint stencil_pass_depth_fail_op:3;
GLuint stencil_fail_op:3;
GLuint stencil_func:3;
GLuint stencil_enable:1;
} ds0;
struct {
GLuint bf_stencil_write_mask:8;
GLuint bf_stencil_test_mask:8;
GLuint stencil_write_mask:8;
GLuint stencil_test_mask:8;
} ds1;
struct {
GLuint pad0:25;
GLuint depth_write_enable:1;
GLuint depth_test_func:3;
GLuint pad1:1;
GLuint depth_test_enable:1;
} ds2;
};
struct brw_cc_unit_state
{
@ -752,8 +850,6 @@ struct brw_cc_unit_state
} cc7;
};
struct brw_sf_unit_state
{
struct thread0 thread0;

View file

@ -0,0 +1,296 @@
/*
* Copyright © 2009 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "brw_util.h"
#include "intel_batchbuffer.h"
#include "main/macros.h"
#include "main/enums.h"
struct brw_blend_state_key {
GLboolean color_blend, alpha_enabled;
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;
GLboolean dither;
};
static void
blend_state_populate_key(struct brw_context *brw,
struct brw_blend_state_key *key)
{
GLcontext *ctx = &brw->intel.ctx;
memset(key, 0, sizeof(*key));
/* _NEW_COLOR */
if (ctx->Color._LogicOpEnabled)
key->logic_op = ctx->Color.LogicOp;
else
key->logic_op = GL_COPY;
/* _NEW_COLOR */
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;
}
/* _NEW_COLOR */
key->alpha_enabled = ctx->Color.AlphaEnabled;
if (key->alpha_enabled) {
key->alpha_func = ctx->Color.AlphaFunc;
}
/* _NEW_COLOR */
key->dither = ctx->Color.DitherFlag;
}
/**
* Creates the state cache entry for the given CC unit key.
*/
static drm_intel_bo *
blend_state_create_from_key(struct brw_context *brw,
struct brw_blend_state_key *key)
{
struct gen6_blend_state blend;
drm_intel_bo *bo;
memset(&blend, 0, sizeof(blend));
if (key->logic_op != GL_COPY) {
blend.blend1.logic_op_enable = 1;
blend.blend1.logic_op_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;
}
blend.blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
blend.blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
blend.blend0.blend_func = brw_translate_blend_equation(eqRGB);
blend.blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
blend.blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
blend.blend0.ia_blend_func = brw_translate_blend_equation(eqA);
blend.blend0.blend_enable = 1;
blend.blend0.ia_blend_enable = (srcA != srcRGB ||
dstA != dstRGB ||
eqA != eqRGB);
}
if (key->alpha_enabled) {
blend.blend1.alpha_test_enable = 1;
blend.blend1.alpha_test_func = intel_translate_compare_func(key->alpha_func);
}
if (key->dither) {
blend.blend1.dither_enable = 1;
blend.blend1.y_dither_offset = 0;
blend.blend1.x_dither_offset = 0;
}
bo = brw_upload_cache(&brw->cache, BRW_BLEND_STATE,
key, sizeof(*key),
NULL, 0,
&blend, sizeof(blend));
return bo;
}
static void
prepare_blend_state(struct brw_context *brw)
{
struct brw_blend_state_key key;
blend_state_populate_key(brw, &key);
drm_intel_bo_unreference(brw->cc.blend_state_bo);
brw->cc.blend_state_bo = brw_search_cache(&brw->cache, BRW_BLEND_STATE,
&key, sizeof(key),
NULL, 0,
NULL);
if (brw->cc.blend_state_bo == NULL)
brw->cc.blend_state_bo = blend_state_create_from_key(brw, &key);
}
const struct brw_tracked_state gen6_blend_state = {
.dirty = {
.mesa = _NEW_COLOR,
.brw = 0,
.cache = 0,
},
.prepare = prepare_blend_state,
};
struct brw_color_calc_state_key {
GLubyte blend_constant_color[4];
GLclampf alpha_ref;
GLubyte stencil_ref[2];
};
static void
color_calc_state_populate_key(struct brw_context *brw,
struct brw_color_calc_state_key *key)
{
GLcontext *ctx = &brw->intel.ctx;
memset(key, 0, sizeof(*key));
/* _NEW_STENCIL */
if (ctx->Stencil._Enabled) {
const unsigned back = ctx->Stencil._BackFace;
key->stencil_ref[0] = ctx->Stencil.Ref[0];
if (ctx->Stencil._TestTwoSide)
key->stencil_ref[1] = ctx->Stencil.Ref[back];
}
/* _NEW_COLOR */
if (ctx->Color.AlphaEnabled)
key->alpha_ref = ctx->Color.AlphaRef;
key->blend_constant_color[0] = ctx->Color.BlendColor[0];
key->blend_constant_color[1] = ctx->Color.BlendColor[1];
key->blend_constant_color[2] = ctx->Color.BlendColor[2];
key->blend_constant_color[3] = ctx->Color.BlendColor[3];
}
/**
* Creates the state cache entry for the given CC state key.
*/
static drm_intel_bo *
color_calc_state_create_from_key(struct brw_context *brw,
struct brw_color_calc_state_key *key)
{
struct gen6_color_calc_state cc;
drm_intel_bo *bo;
memset(&cc, 0, sizeof(cc));
cc.cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
UNCLAMPED_FLOAT_TO_UBYTE(cc.cc1.alpha_ref_fi.ui, key->alpha_ref);
cc.cc0.stencil_ref = key->stencil_ref[0];
cc.cc0.bf_stencil_ref = key->stencil_ref[1];
cc.constant_r = key->blend_constant_color[0];
cc.constant_g = key->blend_constant_color[1];
cc.constant_b = key->blend_constant_color[2];
cc.constant_a = key->blend_constant_color[3];
bo = brw_upload_cache(&brw->cache, BRW_COLOR_CALC_STATE,
key, sizeof(*key),
NULL, 0,
&cc, sizeof(cc));
return bo;
}
static void
prepare_color_calc_state(struct brw_context *brw)
{
struct brw_color_calc_state_key key;
color_calc_state_populate_key(brw, &key);
drm_intel_bo_unreference(brw->cc.state_bo);
brw->cc.state_bo = brw_search_cache(&brw->cache, BRW_COLOR_CALC_STATE,
&key, sizeof(key),
NULL, 0,
NULL);
if (brw->cc.state_bo == NULL)
brw->cc.state_bo = color_calc_state_create_from_key(brw, &key);
}
const struct brw_tracked_state gen6_color_calc_state = {
.dirty = {
.mesa = _NEW_COLOR,
.brw = 0,
.cache = 0,
},
.prepare = prepare_color_calc_state,
};
static void upload_cc_state_pointers(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
BEGIN_BATCH(4);
OUT_BATCH(CMD_3D_CC_STATE_POINTERS << 16 | (4 - 2));
OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
OUT_RELOC(brw->cc.blend_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
OUT_RELOC(brw->cc.depth_stencil_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
ADVANCE_BATCH();
}
static void prepare_cc_state_pointers(struct brw_context *brw)
{
brw_add_validated_bo(brw, brw->cc.state_bo);
brw_add_validated_bo(brw, brw->cc.blend_state_bo);
brw_add_validated_bo(brw, brw->cc.depth_stencil_state_bo);
}
const struct brw_tracked_state gen6_cc_state_pointers = {
.dirty = {
.mesa = 0,
.brw = BRW_NEW_BATCH,
.cache = (CACHE_NEW_BLEND_STATE |
CACHE_NEW_COLOR_CALC_STATE |
CACHE_NEW_DEPTH_STENCIL_STATE)
},
.prepare = prepare_cc_state_pointers,
.emit = upload_cc_state_pointers,
};

View file

@ -0,0 +1,169 @@
/*
* Copyright © 2009 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#include "brw_context.h"
#include "brw_state.h"
#include "brw_defines.h"
#include "brw_util.h"
#include "main/macros.h"
#include "main/enums.h"
struct brw_depth_stencil_state_key {
GLenum depth_func;
GLboolean depth_test, depth_write;
GLboolean stencil, stencil_two_side;
GLenum stencil_func[2], stencil_fail_op[2];
GLenum stencil_pass_depth_fail_op[2], stencil_pass_depth_pass_op[2];
GLubyte stencil_write_mask[2], stencil_test_mask[2];
};
static void
depth_stencil_state_populate_key(struct brw_context *brw,
struct brw_depth_stencil_state_key *key)
{
GLcontext *ctx = &brw->intel.ctx;
const unsigned back = ctx->Stencil._BackFace;
memset(key, 0, sizeof(*key));
/* _NEW_STENCIL */
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_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_write_mask[1] = ctx->Stencil.WriteMask[back];
key->stencil_test_mask[1] = ctx->Stencil.ValueMask[back];
}
key->depth_test = ctx->Depth.Test;
if (key->depth_test) {
key->depth_func = ctx->Depth.Func;
key->depth_write = ctx->Depth.Mask;
}
}
/**
* Creates the state cache entry for the given DEPTH_STENCIL_STATE state key.
*/
static dri_bo *
depth_stencil_state_create_from_key(struct brw_context *brw,
struct brw_depth_stencil_state_key *key)
{
struct gen6_depth_stencil_state ds;
dri_bo *bo;
memset(&ds, 0, sizeof(ds));
/* _NEW_STENCIL */
if (key->stencil) {
ds.ds0.stencil_enable = 1;
ds.ds0.stencil_func =
intel_translate_compare_func(key->stencil_func[0]);
ds.ds0.stencil_fail_op =
intel_translate_stencil_op(key->stencil_fail_op[0]);
ds.ds0.stencil_pass_depth_fail_op =
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[0]);
ds.ds0.stencil_pass_depth_pass_op =
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[0]);
ds.ds1.stencil_write_mask = key->stencil_write_mask[0];
ds.ds1.stencil_test_mask = key->stencil_test_mask[0];
if (key->stencil_two_side) {
ds.ds0.bf_stencil_enable = 1;
ds.ds0.bf_stencil_func =
intel_translate_compare_func(key->stencil_func[1]);
ds.ds0.bf_stencil_fail_op =
intel_translate_stencil_op(key->stencil_fail_op[1]);
ds.ds0.bf_stencil_pass_depth_fail_op =
intel_translate_stencil_op(key->stencil_pass_depth_fail_op[1]);
ds.ds0.bf_stencil_pass_depth_pass_op =
intel_translate_stencil_op(key->stencil_pass_depth_pass_op[1]);
ds.ds1.bf_stencil_write_mask = key->stencil_write_mask[1];
ds.ds1.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]))
ds.ds0.stencil_write_enable = 1;
}
/* _NEW_DEPTH */
if (key->depth_test) {
ds.ds2.depth_test_enable = 1;
ds.ds2.depth_test_func = intel_translate_compare_func(key->depth_func);
ds.ds2.depth_write_enable = key->depth_write;
}
bo = brw_upload_cache(&brw->cache, BRW_DEPTH_STENCIL_STATE,
key, sizeof(*key),
NULL, 0,
&ds, sizeof(ds));
return bo;
}
static void
prepare_depth_stencil_state(struct brw_context *brw)
{
struct brw_depth_stencil_state_key key;
depth_stencil_state_populate_key(brw, &key);
dri_bo_unreference(brw->cc.depth_stencil_state_bo);
brw->cc.depth_stencil_state_bo = brw_search_cache(&brw->cache,
BRW_DEPTH_STENCIL_STATE,
&key, sizeof(key),
NULL, 0,
NULL);
if (brw->cc.depth_stencil_state_bo == NULL)
brw->cc.depth_stencil_state_bo =
depth_stencil_state_create_from_key(brw, &key);
}
const struct brw_tracked_state gen6_depth_stencil_state = {
.dirty = {
.mesa = _NEW_DEPTH | _NEW_STENCIL,
.brw = 0,
.cache = 0,
},
.prepare = prepare_depth_stencil_state,
};