r600g: add support for constants in memory buffers.
authorDave Airlie <airlied@redhat.com>
Tue, 7 Sep 2010 22:41:57 +0000 (08:41 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 7 Sep 2010 22:41:57 +0000 (08:41 +1000)
DX9 constants were in the constant file, and evergreen no longer support
cfile. r600/700 can also use constants in memory buffers, so add the code
(disabled for now) to enable that as precursor for evergreen.

14 files changed:
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_asm.h
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_context.h
src/gallium/drivers/r600/r600_hw_states.c
src/gallium/drivers/r600/r600_screen.c
src/gallium/drivers/r600/r600_screen.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_states_inc.h
src/gallium/drivers/r600/radeon.h
src/gallium/winsys/r600/drm/r600_state.c
src/gallium/winsys/r600/drm/r600_states.h

index bf3d31cd2b0c2be1d4facc73e90f0963f387be94..b62354fe91ac5669742eba1fbb7fd4391cc307ec 100644 (file)
@@ -180,6 +180,10 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
        /* each alu use 2 dwords */
        bc->cf_last->ndw += 2;
        bc->ndw += 2;
+
+       if (bc->use_mem_constant)
+               bc->cf_last->kcache0_mode = 2;
+
        return 0;
 }
 
@@ -392,7 +396,9 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
        switch (cf->inst) {
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
-               bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1);
+               bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
+                       S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache0_mode);
+
                bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) |
                                        S_SQ_CF_ALU_WORD1_BARRIER(1) |
                                        S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
index 9e65fcdd4fa14b83be1c85eebe1df59becd2decd..0d75d99310e3b40ba1ff20e4e467eae087684d3e 100644 (file)
@@ -120,6 +120,7 @@ struct r600_bc_cf {
        unsigned                        cond;
        unsigned                        pop_count;
        unsigned                        cf_addr; /* control flow addr */
+       unsigned                        kcache0_mode;
        struct list_head                alu;
        struct list_head                tex;
        struct list_head                vtx;
@@ -151,6 +152,7 @@ struct r600_cf_callstack {
 struct r600_bc {
        enum radeon_family              family;
        int chiprev; /* 0 - r600, 1 - r700, 2 - evergreen */
+       unsigned                        use_mem_constant; 
        struct list_head                cf;
        struct r600_bc_cf               *cf_last;
        unsigned                        ndw;
index 7829a479c2e0b07015f5b06d368ae5457a1b73de..d8188ae65621d3b88a9f3835c56dc75939632d4d 100644 (file)
@@ -56,6 +56,9 @@ u32 r600_domain_from_usage(unsigned usage)
        if (usage & PIPE_BIND_INDEX_BUFFER) {
            domain |= RADEON_GEM_DOMAIN_GTT;
        }
+       if (usage & PIPE_BIND_CONSTANT_BUFFER) {
+           domain |= RADEON_GEM_DOMAIN_VRAM;
+       }
 
        return domain;
 }
@@ -79,7 +82,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
        rbuffer->base.b.screen = screen;
        rbuffer->base.vtbl = &r600_buffer_vtbl;
 
-       if (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
+       if ((rscreen->use_mem_constant == FALSE) && (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER)) {
                desc.alignment = alignment;
                desc.usage = rbuffer->base.b.bind;
                rbuffer->pb = pb_malloc_buffer_create(rbuffer->base.b.width0,
index 239c1a3adeb09e9c9458907e4622b421685d9885..eb370698bbdcc53d1c1fb13fb334084fb4b97714 100644 (file)
@@ -260,5 +260,11 @@ uint32_t r600_translate_texformat(enum pipe_format format,
 extern void r600_queries_resume(struct pipe_context *ctx);
 extern void r600_queries_suspend(struct pipe_context *ctx);
 
+void r600_set_constant_buffer_file(struct pipe_context *ctx,
+                                  uint shader, uint index,
+                                  struct pipe_resource *buffer);
+void r600_set_constant_buffer_mem(struct pipe_context *ctx,
+                                 uint shader, uint index,
+                                 struct pipe_resource *buffer);
 
 #endif
index 948ae61c2e5f0bfbdc4fcb9336e01f873effe9a0..55723360bf6d5565b663ffd764c20ecc88939e77 100644 (file)
@@ -789,7 +789,8 @@ static void r600_init_config(struct r600_context *rctx)
                break;
        }
 
-       rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
+       if (!rctx->screen->use_mem_constant)
+               rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
 
        rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
        rctx->config.states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
@@ -1033,3 +1034,96 @@ struct r600_context_hw_state_vtbl r600_hw_state_vtbl = {
        .ps_shader = r600_ps_shader,
        .init_config = r600_init_config,
 };
+
+void r600_set_constant_buffer_file(struct pipe_context *ctx,
+                                  uint shader, uint index,
+                                  struct pipe_resource *buffer)
+{
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_context *rctx = r600_context(ctx);
+       unsigned nconstant = 0, i, type, shader_class;
+       struct radeon_state *rstate, *rstates;
+       struct pipe_transfer *transfer;
+       u32 *ptr;
+
+       type = R600_STATE_CONSTANT;
+
+       switch (shader) {
+       case PIPE_SHADER_VERTEX:
+               shader_class = R600_SHADER_VS;
+               rstates = rctx->vs_constant;
+               break;
+       case PIPE_SHADER_FRAGMENT:
+               shader_class = R600_SHADER_PS;
+               rstates = rctx->ps_constant;
+               break;
+       default:
+               R600_ERR("unsupported %d\n", shader);
+               return;
+       }
+       if (buffer && buffer->width0 > 0) {
+               nconstant = buffer->width0 / 16;
+               ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
+               if (ptr == NULL)
+                       return;
+               for (i = 0; i < nconstant; i++) {
+                       rstate = &rstates[i];
+                       radeon_state_init(rstate, rscreen->rw, type, i, shader_class);
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
+                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
+                       if (radeon_state_pm4(rstate))
+                               return;
+                       radeon_draw_bind(&rctx->draw, rstate);
+               }
+               pipe_buffer_unmap(ctx, buffer, transfer);
+       }
+}
+
+void r600_set_constant_buffer_mem(struct pipe_context *ctx,
+                                 uint shader, uint index,
+                                 struct pipe_resource *buffer)
+{
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_context *rctx = r600_context(ctx);
+       unsigned nconstant = 0, i, type, shader_class, size;
+       struct radeon_state *rstate, *rstates;
+       struct r600_resource *rbuffer = (struct r600_resource*)buffer;
+       u32 *ptr;
+
+       type = R600_STATE_CBUF;
+
+       switch (shader) {
+       case PIPE_SHADER_VERTEX:
+               shader_class = R600_SHADER_VS;
+               rstates = rctx->vs_constant;
+               break;
+       case PIPE_SHADER_FRAGMENT:
+               shader_class = R600_SHADER_PS;
+               rstates = rctx->ps_constant;
+               break;
+       default:
+               R600_ERR("unsupported %d\n", shader);
+               return;
+       }
+
+       rstate = &rstates[0];
+
+#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
+
+       nconstant = buffer->width0 / 16;
+       size = ALIGN_DIVUP(nconstant, 16);
+               
+       radeon_state_init(rstate, rscreen->rw, type, 0, shader_class);
+       rstate->states[R600_VS_CBUF__ALU_CONST_BUFFER_SIZE_VS_0] = size;
+       rstate->states[R600_VS_CBUF__ALU_CONST_CACHE_VS_0] = 0;
+
+       rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+       rstate->nbo = 1;
+       rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM;
+       if (radeon_state_pm4(rstate))
+               return;
+       radeon_draw_bind(&rctx->draw, rstate);
+}
+
index a047a49a6c55cd7d55e4f5dfd90b54dedf4fb8bb..54a61ddfb33072cc5c358c9826a745d6a33c09fe 100644 (file)
@@ -240,6 +240,9 @@ struct pipe_screen *r600_screen_create(struct radeon *rw)
        if (rscreen == NULL) {
                return NULL;
        }
+       
+       /* don't enable mem constant for r600 yet */
+       rscreen->use_mem_constant = FALSE;
 
        switch (family) {
        case CHIP_R600:
index b9938f117a83d95bfd2d6a10859afbd711bbd883..4be77865fbd6cf973a7190e5c5e929b77db8c190 100644 (file)
@@ -52,6 +52,7 @@ struct r600_screen {
        struct pipe_screen              screen;
        struct radeon                   *rw;
        enum chip_class                 chip_class;
+       boolean use_mem_constant;
 };
 
 static INLINE struct r600_screen *r600_screen(struct pipe_screen *screen)
index 1273cd62a2831ccecf3f9fcd019b56ceabfbc83e..b643157f56a71920c344cec96c003170f845f99d 100644 (file)
@@ -113,6 +113,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
        if (rpshader == NULL)
                return -ENOMEM;
        rpshader->shader.family = radeon_get_family(rscreen->rw);
+       rpshader->shader.use_mem_constant = rscreen->use_mem_constant;
        r = r600_shader_from_tgsi(tokens, &rpshader->shader);
        if (r) {
                R600_ERR("translation from TGSI failed !\n");
@@ -311,6 +312,7 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
        r = r600_bc_init(ctx.bc, shader->family);
        if (r)
                return r;
+       ctx.bc->use_mem_constant = shader->use_mem_constant;
        ctx.tokens = tokens;
        tgsi_scan_shader(tokens, &ctx.info);
        tgsi_parse_init(&ctx.parse, tokens);
@@ -346,7 +348,11 @@ int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *s
                                                ctx.info.file_count[TGSI_FILE_INPUT];
        ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] +
                                                ctx.info.file_count[TGSI_FILE_OUTPUT];
-       ctx.file_offset[TGSI_FILE_CONSTANT] = 256;
+       if (ctx.shader->use_mem_constant)
+               ctx.file_offset[TGSI_FILE_CONSTANT] = 128;
+       else
+               ctx.file_offset[TGSI_FILE_CONSTANT] = 256;
+
        ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253;
        ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] +
                        ctx.info.file_count[TGSI_FILE_TEMPORARY];
index 7c722c07cbe365d96c03fd4f0dee9a027092d0d9..fba4a2b3b8af918de5c3898d4468cbb46fc60e00 100644 (file)
@@ -43,6 +43,7 @@ struct r600_shader {
        struct r600_shader_io   output[32];
        enum radeon_family      family;
        boolean                 uses_kill;
+       boolean                 use_mem_constant;
 };
 
 #endif
index 780a867f95e9fcb9270ddd8c1a07d70fd6b7cfc5..93b0cf1a534cf4807e1c754ddab6dfd91fab4672 100644 (file)
@@ -374,52 +374,6 @@ static void r600_set_clip_state(struct pipe_context *ctx,
        rctx->clip = rstate;
 }
 
-static void r600_set_constant_buffer(struct pipe_context *ctx,
-                                       uint shader, uint index,
-                                       struct pipe_resource *buffer)
-{
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
-       struct r600_context *rctx = r600_context(ctx);
-       unsigned nconstant = 0, i, type, shader_class;
-       struct radeon_state *rstate, *rstates;
-       struct pipe_transfer *transfer;
-       u32 *ptr;
-
-       type = R600_STATE_CONSTANT;
-
-       switch (shader) {
-       case PIPE_SHADER_VERTEX:
-               shader_class = R600_SHADER_VS;
-               rstates = rctx->vs_constant;
-               break;
-       case PIPE_SHADER_FRAGMENT:
-               shader_class = R600_SHADER_PS;
-               rstates = rctx->ps_constant;
-               break;
-       default:
-               R600_ERR("unsupported %d\n", shader);
-               return;
-       }
-       if (buffer && buffer->width0 > 0) {
-               nconstant = buffer->width0 / 16;
-               ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
-               if (ptr == NULL)
-                       return;
-               for (i = 0; i < nconstant; i++) {
-                       rstate = &rstates[i];
-                       radeon_state_init(rstate, rscreen->rw, type, i, shader_class);
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
-                       rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
-                       if (radeon_state_pm4(rstate))
-                               return;
-                       radeon_draw_bind(&rctx->draw, rstate);
-               }
-               pipe_buffer_unmap(ctx, buffer, transfer);
-       }
-}
-
 static void r600_set_framebuffer_state(struct pipe_context *ctx,
                                        const struct pipe_framebuffer_state *state)
 {
@@ -555,7 +509,10 @@ void r600_init_state_functions(struct r600_context *rctx)
        rctx->context.delete_vs_state = r600_delete_state;
        rctx->context.set_blend_color = r600_set_blend_color;
        rctx->context.set_clip_state = r600_set_clip_state;
-       rctx->context.set_constant_buffer = r600_set_constant_buffer;
+       if (rctx->screen->use_mem_constant)
+               rctx->context.set_constant_buffer = r600_set_constant_buffer_mem;
+       else
+               rctx->context.set_constant_buffer = r600_set_constant_buffer_file;
        rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_view;
        rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
        rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
index 5367af5850e5ce344bcf8eb3c1ba0396fc781e67..0f8a2d74616987987fc529b1855d07c153c8fd48 100644 (file)
 #define R600_PS_SHADER_SIZE            39
 #define R600_PS_SHADER_PM4 128         
 
+/* R600_VS_CBUF */
+#define R600_VS_CBUF__ALU_CONST_BUFFER_SIZE_VS_0               0
+#define R600_VS_CBUF__ALU_CONST_CACHE_VS_0             1
+#define R600_VS_CBUF_SIZE              2
+#define R600_VS_CBUF_PM4 128           
+
+/* R600_PS_CBUF */
+#define R600_PS_CBUF__ALU_CONST_BUFFER_SIZE_PS_0               0
+#define R600_PS_CBUF__ALU_CONST_CACHE_PS_0             1
+#define R600_PS_CBUF_SIZE              2
+#define R600_PS_CBUF_PM4 128           
+
 /* R600_PS_CONSTANT */
 #define R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0           0
 #define R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0           1
index cf26ecfe231eea80e92c6dbbdb3a0ce90ffe3675..0a8cb73e7dc11c7c5849d51d66630004061c9f1e 100644 (file)
@@ -194,6 +194,7 @@ enum r600_stype {
        R600_STATE_DSA,
        R600_STATE_SHADER,          /* has PS,VS,GS,FS variants */
        R600_STATE_CONSTANT,        /* has PS,VS,GS,FS variants */
+       R600_STATE_CBUF,        /* has PS,VS,GS,FS variants */
        R600_STATE_RESOURCE,        /* has PS,VS,GS,FS variants */
        R600_STATE_SAMPLER,         /* has PS,VS,GS,FS variants */
        R600_STATE_SAMPLER_BORDER,  /* has PS,VS,GS,FS variants */
index 71d65f0feab648c87bdce1000ddffe06c6933ac6..23eed81e04d626b915d6c39d22cfb6fe9e40953d 100644 (file)
@@ -65,6 +65,7 @@ struct radeon_stype_info r600_stypes[] = {
        { R600_STATE_BLEND, 1, 0, r600_state_pm4_generic, SUB_NONE(BLEND), },
        { R600_STATE_DSA, 1, 0, r600_state_pm4_generic, SUB_NONE(DSA), },
        { R600_STATE_SHADER, 1, 0, r600_state_pm4_shader, { SUB_PS(PS_SHADER), SUB_VS(VS_SHADER) } },
+       { R600_STATE_CBUF, 1, 0, r600_state_pm4_shader,  { SUB_PS(PS_CBUF), SUB_VS(VS_CBUF) } },
        { R600_STATE_CONSTANT, 256, 0x10, r600_state_pm4_generic,  { SUB_PS(PS_CONSTANT), SUB_VS(VS_CONSTANT) } },
        { R600_STATE_RESOURCE, 160, 0x1c, r600_state_pm4_resource, { SUB_PS(PS_RESOURCE), SUB_VS(VS_RESOURCE), SUB_GS(GS_RESOURCE), SUB_FS(FS_RESOURCE)} },
        { R600_STATE_SAMPLER, 18, 0xc, r600_state_pm4_generic, { SUB_PS(PS_SAMPLER), SUB_VS(VS_SAMPLER), SUB_GS(GS_SAMPLER) } },
index 09d79d498d89def18f676ab282f934715b5c1eb0..06f6c7773d2dde72e971a1abf899be55becf3779 100644 (file)
@@ -269,6 +269,16 @@ static const struct radeon_register R600_names_PS_SHADER[] = {
        {0x000288CC, 0, 0, "SQ_PGM_CF_OFFSET_PS"},
 };
 
+static const struct radeon_register R600_names_VS_CBUF[] = {
+       {0x00028180, 0, 0, "ALU_CONST_BUFFER_SIZE_VS_0"},
+       {0x00028980, 1, 0, "ALU_CONST_CACHE_VS_0"},
+};
+
+static const struct radeon_register R600_names_PS_CBUF[] = {
+       {0x00028140, 0, 0, "ALU_CONST_BUFFER_SIZE_PS_0"},
+       {0x00028940, 1, 0, "ALU_CONST_CACHE_PS_0"},
+};
+
 static const struct radeon_register R600_names_PS_CONSTANT[] = {
        {0x00030000, 0, 0, "SQ_ALU_CONSTANT0_0"},
        {0x00030004, 0, 0, "SQ_ALU_CONSTANT1_0"},