summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2011-03-02 19:41:08 +0100
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2011-03-02 20:59:53 +0100
commitddcb90248fb491a3a9e2ada8c595f94b0bd95515 (patch)
treeb8ec8a04d79dc45145d65df9c9d55b4ed570c550 /src/gallium/drivers/nv50
parent669de7016ce3e95c6d1e4ee8e41b5bfe95f32105 (diff)
nv50: implement independent blend functions for nva3+ and fix cap
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h6
3 files changed, 34 insertions, 6 deletions
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index f2b03e8156..2bc26e5750 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -115,8 +115,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_INDEP_BLEND_ENABLE:
- case PIPE_CAP_INDEP_BLEND_FUNC:
return 1;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return nv50_screen(pscreen)->base.device->chipset >= 0xa3;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 17f272bb3b..2f6fdb4c48 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -88,7 +88,14 @@ nv50_blend_state_create(struct pipe_context *pipe,
{
struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
int i;
- boolean blend_enabled = cso->rt[0].blend_enable;
+ boolean emit_common_func = cso->rt[0].blend_enable;
+
+ const uint32_t chipset = nv50_context(pipe)->screen->base.device->chipset;
+
+ if (chipset >= 0xa3) {
+ SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
+ SB_DATA (so, cso->independent_blend_enable);
+ }
so->pipe = *cso;
@@ -97,14 +104,30 @@ nv50_blend_state_create(struct pipe_context *pipe,
for (i = 0; i < 8; ++i) {
SB_DATA(so, cso->rt[i].blend_enable);
if (cso->rt[i].blend_enable)
- blend_enabled = TRUE;
+ emit_common_func = TRUE;
+ }
+
+ if (chipset >= 0xa3) {
+ emit_common_func = FALSE;
+
+ for (i = 0; i < 8; ++i) {
+ if (!cso->rt[i].blend_enable)
+ continue;
+ SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);
+ SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));
+ SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));
+ }
}
} else {
for (i = 0; i < 8; ++i)
- SB_DATA(so, blend_enabled);
+ SB_DATA(so, cso->rt[0].blend_enable);
}
- if (blend_enabled) {
+ if (emit_common_func) {
SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
index 49f1837bfe..f4e458b0c0 100644
--- a/src/gallium/drivers/nv50/nv50_stateobj.h
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -10,12 +10,16 @@
(so)->state[(so)->size++] = \
((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
+#define SB_BEGIN_3D_(so, m, s) \
+ (so)->state[(so)->size++] = \
+ ((s) << 18) | (NV50_SUBCH_3D << 13) | m
+
#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
struct nv50_blend_stateobj {
struct pipe_blend_state pipe;
int size;
- uint32_t state[29];
+ uint32_t state[78];
};
struct nv50_tsc_entry {