Example #1
0
static void r300_update_ztop(struct r300_context* r300)
{
    struct r300_ztop_state* ztop_state =
        (struct r300_ztop_state*)r300->ztop_state.state;
    uint32_t old_ztop = ztop_state->z_buffer_top;

    /* This is important enough that I felt it warranted a comment.
     *
     * According to the docs, these are the conditions where ZTOP must be
     * disabled:
     * 1) Alpha testing enabled
     * 2) Texture kill instructions in fragment shader
     * 3) Chroma key culling enabled
     * 4) W-buffering enabled
     *
     * The docs claim that for the first three cases, if no ZS writes happen,
     * then ZTOP can be used.
     *
     * (3) will never apply since we do not support chroma-keyed operations.
     * (4) will need to be re-examined (and this comment updated) if/when
     * Hyper-Z becomes supported.
     *
     * Additionally, the following conditions require disabled ZTOP:
     * 5) Depth writes in fragment shader
     * 6) Outstanding occlusion queries
     *
     * This register causes stalls all the way from SC to CB when changed,
     * but it is buffered on-chip so it does not hurt to write it if it has
     * not changed.
     *
     * ~C.
     */

    /* ZS writes */
    if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
           (r300_dsa_alpha_test_enabled(r300->dsa_state.state) ||  /* (1) */
            r300_fs(r300)->shader->info.uses_kill)) {              /* (2) */
        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
    } else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */
        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
    } else if (r300->query_current) {                              /* (6) */
        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
    } else {
        ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
    }
    if (ztop_state->z_buffer_top != old_ztop)
        r300_mark_atom_dirty(r300, &r300->ztop_state);
}
Example #2
0
static boolean r300_hiz_allowed(struct r300_context *r300)
{
    struct r300_dsa_state *dsa = r300->dsa_state.state;
    struct r300_screen *r300screen = r300->screen;

    if (r300_fragment_shader_writes_depth(r300_fs(r300)))
        return FALSE;

    if (r300->query_current)
        return FALSE;

    /* If the depth function is inverted, HiZ must be disabled. */
    if (!r300_is_hiz_func_valid(r300))
        return FALSE;

    /* if stencil fail/zfail op is not KEEP */
    if (r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[0]) ||
        r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[1]))
        return FALSE;

    if (dsa->dsa.depth.enabled) {
        /* if depth func is EQUAL pre-r500 */
        if (dsa->dsa.depth.func == PIPE_FUNC_EQUAL && !r300screen->caps.is_r500)
            return FALSE;

        /* if depth func is NOTEQUAL */
        if (dsa->dsa.depth.func == PIPE_FUNC_NOTEQUAL)
            return FALSE;
    }
    return TRUE;
}
Example #3
0
void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state)
{
    struct r300_fragment_shader *fs = r300_fs(r300);
    struct rc_constant_list *constants = &fs->shader->code.constants;
    unsigned i;
    unsigned count = fs->shader->rc_state_count;
    unsigned first = fs->shader->externals_count;
    unsigned end = constants->Count;
    CS_LOCALS(r300);

    if (count == 0)
        return;

    BEGIN_CS(size);
    for(i = first; i < end; ++i) {
        if (constants->Constants[i].Type == RC_CONSTANT_STATE) {
            float data[4];

            get_rc_constant_state(data, r300, &constants->Constants[i]);

            OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
                       R500_GA_US_VECTOR_INDEX_TYPE_CONST |
                       (i & R500_GA_US_VECTOR_INDEX_MASK));
            OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, 4);
            OUT_CS_TABLE(data, 4);
        }
    }
    END_CS;
}
Example #4
0
void r500_emit_fs(struct r300_context* r300, unsigned size, void *state)
{
    struct r300_fragment_shader *fs = r300_fs(r300);
    CS_LOCALS(r300);

    WRITE_CS_TABLE(fs->shader->cb_code, fs->shader->cb_code_size);
}
Example #5
0
void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state)
{
    struct r300_fragment_shader *fs = r300_fs(r300);
    struct rc_constant_list *constants = &fs->shader->code.constants;
    unsigned i;
    unsigned count = fs->shader->rc_state_count;
    unsigned first = fs->shader->externals_count;
    unsigned end = constants->Count;
    unsigned j;
    CS_LOCALS(r300);

    if (count == 0)
        return;

    BEGIN_CS(size);
    for(i = first; i < end; ++i) {
        if (constants->Constants[i].Type == RC_CONSTANT_STATE) {
            float data[4];

            get_rc_constant_state(data, r300, &constants->Constants[i]);

            OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4);
            for (j = 0; j < 4; j++)
                OUT_CS(pack_float24(data[j]));
        }
    }
    END_CS;
}
Example #6
0
void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
{
    struct r300_fragment_shader *fs = r300_fs(r300);
    struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
    unsigned count = fs->shader->externals_count;
    unsigned i, j;
    CS_LOCALS(r300);

    if (count == 0)
        return;

    BEGIN_CS(size);
    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4);
    if (buf->remap_table){
        for (i = 0; i < count; i++) {
            float *data = (float*)&buf->ptr[buf->remap_table[i]*4];
            for (j = 0; j < 4; j++)
                OUT_CS(pack_float24(data[j]));
        }
    } else {
        for (i = 0; i < count; i++)
            for (j = 0; j < 4; j++)
                OUT_CS(pack_float24(*(float*)&buf->ptr[i*4+j]));
    }

    END_CS;
}
Example #7
0
boolean r300_pick_fragment_shader(struct r300_context* r300)
{
    struct r300_fragment_shader* fs = r300_fs(r300);
    struct r300_fragment_program_external_state state = {{{ 0 }}};
    struct r300_fragment_shader_code* ptr;

    get_external_state(r300, &state);

    if (!fs->first) {
        /* Build the fragment shader for the first time. */
        fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code);

        memcpy(&fs->shader->compare_state, &state,
            sizeof(struct r300_fragment_program_external_state));
        r300_translate_fragment_shader(r300, fs->shader, fs->state.tokens);
        return TRUE;

    } else {
        /* Check if the currently-bound shader has been compiled
         * with the texture-compare state we need. */
        if (memcmp(&fs->shader->compare_state, &state, sizeof(state)) != 0) {
            /* Search for the right shader. */
            ptr = fs->first;
            while (ptr) {
                if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) {
                    if (fs->shader != ptr) {
                        fs->shader = ptr;
                        return TRUE;
                    }
                    /* The currently-bound one is OK. */
                    return FALSE;
                }
                ptr = ptr->next;
            }

            /* Not found, gotta compile a new one. */
            ptr = CALLOC_STRUCT(r300_fragment_shader_code);
            ptr->next = fs->first;
            fs->first = fs->shader = ptr;

            ptr->compare_state = state;
            r300_translate_fragment_shader(r300, ptr, fs->state.tokens);
            return TRUE;
        }
    }

    return FALSE;
}
Example #8
0
void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
{
    struct r300_fragment_shader *fs = r300_fs(r300);
    struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
    unsigned count = fs->shader->externals_count;
    CS_LOCALS(r300);

    if (count == 0)
        return;

    BEGIN_CS(size);
    OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4);
    if (buf->remap_table){
        for (unsigned i = 0; i < count; i++) {
            uint32_t *data = &buf->ptr[buf->remap_table[i]*4];
            OUT_CS_TABLE(data, 4);
        }
    } else {
        OUT_CS_TABLE(buf->ptr, count * 4);
    }
    END_CS;
}