summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-07-18 05:58:42 +0800
committerChia-I Wu <[email protected]>2013-08-13 15:52:41 +0800
commit5e30ffbda6259c2bbd519c5fe092df1db1d0c94d (patch)
tree44fd7927526598222b4d69be0f5f1206d2151153 /src
parent5df62dce347eb8046a38630280aa043e075ac56f (diff)
ilo: support copying constant buffer 0 to PCB
Add ILO_KERNEL_PCB_CBUF0_SIZE so that a kernel can specify how many bytes of constant buffer 0 need to be copied to PCB.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline.h2
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c100
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c18
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.c3
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.h1
5 files changed, 105 insertions, 19 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline.h b/src/gallium/drivers/ilo/ilo_3d_pipeline.h
index ba3a4be584f..5353ae99f81 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline.h
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline.h
@@ -125,6 +125,8 @@ struct ilo_3d_pipeline {
uint32_t SURFACE_STATE[ILO_MAX_WM_SURFACES];
uint32_t SAMPLER_STATE;
uint32_t SAMPLER_BORDER_COLOR_STATE[ILO_MAX_SAMPLERS];
+ uint32_t PUSH_CONSTANT_BUFFER;
+ int PUSH_CONSTANT_BUFFER_size;
} wm;
} state;
};
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index ce1558b694e..dca49311ab3 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -653,8 +653,12 @@ gen6_pipeline_wm(struct ilo_3d_pipeline *p,
struct gen6_pipeline_session *session)
{
/* 3DSTATE_CONSTANT_PS */
- if (session->pcb_state_fs_changed)
- gen6_emit_3DSTATE_CONSTANT_PS(p->dev, NULL, NULL, 0, p->cp);
+ if (session->pcb_state_fs_changed) {
+ gen6_emit_3DSTATE_CONSTANT_PS(p->dev,
+ &p->state.wm.PUSH_CONSTANT_BUFFER,
+ &p->state.wm.PUSH_CONSTANT_BUFFER_size,
+ 1, p->cp);
+ }
/* 3DSTATE_WM */
if (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(BLEND) || DIRTY(DSA) ||
@@ -1189,27 +1193,83 @@ gen6_pipeline_state_pcb(struct ilo_3d_pipeline *p,
struct gen6_pipeline_session *session)
{
/* push constant buffer for VS */
- if (DIRTY(VS) || DIRTY(CLIP)) {
+ if (DIRTY(VS) || DIRTY(CBUF) || DIRTY(CLIP)) {
+ const int cbuf0_size = (ilo->vs) ?
+ ilo_shader_get_kernel_param(ilo->vs,
+ ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
const int clip_state_size = (ilo->vs) ?
ilo_shader_get_kernel_param(ilo->vs,
ILO_KERNEL_VS_PCB_UCP_SIZE) : 0;
+ const int total_size = cbuf0_size + clip_state_size;
- if (clip_state_size) {
+ if (total_size) {
void *pcb;
- p->state.vs.PUSH_CONSTANT_BUFFER_size = clip_state_size;
p->state.vs.PUSH_CONSTANT_BUFFER =
- gen6_emit_push_constant_buffer(p->dev,
- p->state.vs.PUSH_CONSTANT_BUFFER_size, &pcb, p->cp);
+ gen6_emit_push_constant_buffer(p->dev, total_size, &pcb, p->cp);
+ p->state.vs.PUSH_CONSTANT_BUFFER_size = total_size;
+
+ if (cbuf0_size) {
+ const struct ilo_cbuf_state *cbuf =
+ &ilo->cbuf[PIPE_SHADER_VERTEX];
+
+ if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+ memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
+ }
+ else {
+ memcpy(pcb, cbuf->cso[0].user_buffer,
+ cbuf->cso[0].user_buffer_size);
+ memset(pcb + cbuf->cso[0].user_buffer_size, 0,
+ cbuf0_size - cbuf->cso[0].user_buffer_size);
+ }
+
+ pcb += cbuf0_size;
+ }
- memcpy(pcb, &ilo->clip, clip_state_size);
+ if (clip_state_size)
+ memcpy(pcb, &ilo->clip, clip_state_size);
+
+ session->pcb_state_vs_changed = true;
}
- else {
- p->state.vs.PUSH_CONSTANT_BUFFER_size = 0;
+ else if (p->state.vs.PUSH_CONSTANT_BUFFER_size) {
p->state.vs.PUSH_CONSTANT_BUFFER = 0;
+ p->state.vs.PUSH_CONSTANT_BUFFER_size = 0;
+
+ session->pcb_state_vs_changed = true;
}
+ }
- session->pcb_state_vs_changed = true;
+ /* push constant buffer for FS */
+ if (DIRTY(FS) || DIRTY(CBUF)) {
+ const int cbuf0_size = (ilo->fs) ?
+ ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
+
+ if (cbuf0_size) {
+ const struct ilo_cbuf_state *cbuf = &ilo->cbuf[PIPE_SHADER_FRAGMENT];
+ void *pcb;
+
+ p->state.wm.PUSH_CONSTANT_BUFFER =
+ gen6_emit_push_constant_buffer(p->dev, cbuf0_size, &pcb, p->cp);
+ p->state.wm.PUSH_CONSTANT_BUFFER_size = cbuf0_size;
+
+ if (cbuf0_size <= cbuf->cso[0].user_buffer_size) {
+ memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
+ }
+ else {
+ memcpy(pcb, cbuf->cso[0].user_buffer,
+ cbuf->cso[0].user_buffer_size);
+ memset(pcb + cbuf->cso[0].user_buffer_size, 0,
+ cbuf0_size - cbuf->cso[0].user_buffer_size);
+ }
+
+ session->pcb_state_fs_changed = true;
+ }
+ else if (p->state.wm.PUSH_CONSTANT_BUFFER_size) {
+ p->state.wm.PUSH_CONSTANT_BUFFER = 0;
+ p->state.wm.PUSH_CONSTANT_BUFFER_size = 0;
+
+ session->pcb_state_fs_changed = true;
+ }
}
}
@@ -1551,13 +1611,23 @@ gen6_pipeline_estimate_states(const struct ilo_3d_pipeline *p,
}
/* pcb (vs) */
- if (ilo->vs &&
- ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE)) {
- const int pcb_size =
+ if (ilo->vs) {
+ const int cbuf0_size =
+ ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_PCB_CBUF0_SIZE);
+ const int ucp_size =
ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE);
size += ilo_gpe_gen6_estimate_state_size(p->dev,
- ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, pcb_size);
+ ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, cbuf0_size + ucp_size);
+ }
+
+ /* pcb (fs) */
+ if (ilo->fs) {
+ const int cbuf0_size =
+ ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
+
+ size += ilo_gpe_gen6_estimate_state_size(p->dev,
+ ILO_GPE_GEN6_PUSH_CONSTANT_BUFFER, cbuf0_size);
}
return size;
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
index b489624a728..b395f9beffb 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
@@ -754,13 +754,23 @@ gen7_pipeline_estimate_states(const struct ilo_3d_pipeline *p,
}
/* pcb (vs) */
- if (ilo->vs &&
- ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE)) {
- const int pcb_size =
+ if (ilo->vs) {
+ const int cbuf0_size =
+ ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_PCB_CBUF0_SIZE);
+ const int ucp_size =
ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE);
size += ilo_gpe_gen7_estimate_state_size(p->dev,
- ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, pcb_size);
+ ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, cbuf0_size + ucp_size);
+ }
+
+ /* pcb (fs) */
+ if (ilo->fs) {
+ const int cbuf0_size =
+ ilo_shader_get_kernel_param(ilo->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
+
+ size += ilo_gpe_gen7_estimate_state_size(p->dev,
+ ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, cbuf0_size);
}
return size;
diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c
index 0db03966c6b..b1a11a1391b 100644
--- a/src/gallium/drivers/ilo/ilo_shader.c
+++ b/src/gallium/drivers/ilo/ilo_shader.c
@@ -1063,6 +1063,9 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader,
case ILO_KERNEL_SKIP_CBUF0_UPLOAD:
val = false;
break;
+ case ILO_KERNEL_PCB_CBUF0_SIZE:
+ val = 0;
+ break;
case ILO_KERNEL_VS_INPUT_INSTANCEID:
val = shader->info.has_instanceid;
diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h
index 67f190c7bc0..d12b086ec81 100644
--- a/src/gallium/drivers/ilo/ilo_shader.h
+++ b/src/gallium/drivers/ilo/ilo_shader.h
@@ -35,6 +35,7 @@ enum ilo_kernel_param {
ILO_KERNEL_OUTPUT_COUNT,
ILO_KERNEL_URB_DATA_START_REG,
ILO_KERNEL_SKIP_CBUF0_UPLOAD,
+ ILO_KERNEL_PCB_CBUF0_SIZE,
ILO_KERNEL_VS_INPUT_INSTANCEID,
ILO_KERNEL_VS_INPUT_VERTEXID,