static void nv40_query_render_condition(struct pipe_context *pipe, struct pipe_query *pq, boolean condition, enum pipe_render_cond_flag mode) { struct nv30_context *nv30 = nv30_context(pipe); struct nv30_query *q = nv30_query(pq); struct nouveau_pushbuf *push = nv30->base.pushbuf; nv30->render_cond_query = pq; nv30->render_cond_mode = mode; nv30->render_cond_cond = condition; if (!pq) { BEGIN_NV04(push, SUBC_3D(0x1e98), 1); PUSH_DATA (push, 0x01000000); return; } if (mode == PIPE_RENDER_COND_WAIT || mode == PIPE_RENDER_COND_BY_REGION_WAIT) { BEGIN_NV04(push, SUBC_3D(0x0110), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, SUBC_3D(0x1e98), 1); PUSH_DATA (push, 0x02000000 | q->qo[1]->hw->start); }
void nvc0_fragprog_validate(struct nvc0_context *nvc0) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *fp = nvc0->fragprog; if (!nvc0_program_validate(nvc0, fp)) return; nvc0_program_update_context_state(nvc0, fp, 4); if (fp->fp.early_z != nvc0->state.early_z_forced) { nvc0->state.early_z_forced = fp->fp.early_z; IMMED_NVC0(push, NVC0_3D(FORCE_EARLY_FRAGMENT_TESTS), fp->fp.early_z); } BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2); PUSH_DATA (push, 0x51); PUSH_DATA (push, fp->code_base); BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1); PUSH_DATA (push, fp->max_gpr); BEGIN_NVC0(push, SUBC_3D(0x0360), 2); PUSH_DATA (push, 0x20164010); PUSH_DATA (push, 0x20); BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1); PUSH_DATA (push, fp->flags[0]); }
static void nv50_render_condition(struct pipe_context *pipe, struct pipe_query *pq, boolean condition, uint mode) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q; nv50->cond_query = pq; nv50->cond_cond = condition; nv50->cond_mode = mode; PUSH_SPACE(push, 6); if (!pq) { BEGIN_NV04(push, NV50_3D(COND_MODE), 1); PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); return; } q = nv50_query(pq); if (mode == PIPE_RENDER_COND_WAIT || mode == PIPE_RENDER_COND_BY_REGION_WAIT) { BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3); PUSH_DATAh(push, q->bo->offset + q->offset); PUSH_DATA (push, q->bo->offset + q->offset); PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO); }
static void nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) { struct nv30_context *nv30 = nv30_context(pipe); struct nv30_query *q = nv30_query(pq); struct nouveau_pushbuf *push = nv30->base.pushbuf; switch (q->type) { case PIPE_QUERY_TIME_ELAPSED: q->qo[0] = nv30_query_object_new(nv30->screen); if (q->qo[0]) { BEGIN_NV04(push, NV30_3D(QUERY_GET), 1); PUSH_DATA (push, (q->report << 24) | q->qo[0]->hw->start); } break; case PIPE_QUERY_TIMESTAMP: return; default: BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1); PUSH_DATA (push, q->report); break; } if (q->enable) { BEGIN_NV04(push, SUBC_3D(q->enable), 1); PUSH_DATA (push, 1); } }
void nv50_fragprog_validate(struct nv50_context *nv50) { struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *fp = nv50->fragprog; fp->fp.sample_interp = nv50->min_samples > 1; if (!nv50_program_validate(nv50, fp)) return; nv50_program_update_context_state(nv50, fp, 1); BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1); PUSH_DATA (push, fp->max_gpr); BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1); PUSH_DATA (push, fp->max_out); BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1); PUSH_DATA (push, fp->fp.flags[0]); BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1); PUSH_DATA (push, fp->fp.flags[1]); BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); PUSH_DATA (push, fp->code_base); if (nv50->screen->tesla->oclass >= NVA3_3D_CLASS) { BEGIN_NV04(push, SUBC_3D(NVA3_3D_FP_MULTISAMPLE), 1); if (nv50->min_samples > 1 || fp->fp.has_samplemask) PUSH_DATA(push, NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE | (NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK * fp->fp.has_samplemask)); else PUSH_DATA(push, 0); } }
static void nv50_texture_barrier(struct pipe_context *pipe) { struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf; BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1); PUSH_DATA (push, 0x20); }
void nv84_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq) { struct nv50_query *q = nv50_query(pq); unsigned offset = q->offset; PUSH_SPACE(push, 5); PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); BEGIN_NV04(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4); PUSH_DATAh(push, q->bo->offset + offset); PUSH_DATA (push, q->bo->offset + offset); PUSH_DATA (push, q->sequence); PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); }
void nv50_hw_query_pushbuf_submit(struct nouveau_pushbuf *push, uint16_t method, struct nv50_query *q, unsigned result_offset) { struct nv50_hw_query *hq = nv50_hw_query(q); nv50_hw_query_update(q); if (hq->state != NV50_HW_QUERY_STATE_READY) nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, push->client); hq->state = NV50_HW_QUERY_STATE_READY; BEGIN_NV04(push, SUBC_3D(method), 1); PUSH_DATA (push, hq->data[result_offset / 4]); }
void nv50_fragprog_validate(struct nv50_context *nv50) { struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_program *fp = nv50->fragprog; struct pipe_rasterizer_state *rast = &nv50->rast->pipe; if (fp->fp.force_persample_interp != rast->force_persample_interp) { /* Force the program to be reuploaded, which will trigger interp fixups * to get applied */ if (fp->mem) nouveau_heap_free(&fp->mem); fp->fp.force_persample_interp = rast->force_persample_interp; } if (fp->mem && !(nv50->dirty_3d & (NV50_NEW_3D_FRAGPROG | NV50_NEW_3D_MIN_SAMPLES))) return; if (!nv50_program_validate(nv50, fp)) return; nv50_program_update_context_state(nv50, fp, 1); BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1); PUSH_DATA (push, fp->max_gpr); BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1); PUSH_DATA (push, fp->max_out); BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1); PUSH_DATA (push, fp->fp.flags[0]); BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1); PUSH_DATA (push, fp->fp.flags[1]); BEGIN_NV04(push, NV50_3D(FP_START_ID), 1); PUSH_DATA (push, fp->code_base); if (nv50->screen->tesla->oclass >= NVA3_3D_CLASS) { BEGIN_NV04(push, SUBC_3D(NVA3_3D_FP_MULTISAMPLE), 1); if (nv50->min_samples > 1 || fp->fp.has_samplemask) PUSH_DATA(push, NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE | (NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK * fp->fp.has_samplemask)); else PUSH_DATA(push, 0); } }
void nva0_so_target_save_offset(struct pipe_context *pipe, struct pipe_stream_output_target *ptarg, unsigned index, boolean serialize) { struct nv50_so_target *targ = nv50_so_target(ptarg); if (serialize) { struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf; PUSH_SPACE(push, 2); BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); PUSH_DATA (push, 0); } nv50_query(targ->pq)->index = index; nv50_query_end(pipe, targ->pq); }
void nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq) { struct nvc0_query *q = nvc0_query(pq); unsigned offset = q->offset; if (q->type == PIPE_QUERY_SO_OVERFLOW_PREDICATE) offset += 0x20; PUSH_SPACE(push, 5); PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4); PUSH_DATAh(push, q->bo->offset + offset); PUSH_DATA (push, q->bo->offset + offset); PUSH_DATA (push, q->sequence); PUSH_DATA (push, (1 << 12) | NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); }
static void nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq) { struct nv30_context *nv30 = nv30_context(pipe); struct nv30_screen *screen = nv30->screen; struct nv30_query *q = nv30_query(pq); struct nouveau_pushbuf *push = nv30->base.pushbuf; q->qo[1] = nv30_query_object_new(screen); if (q->qo[1]) { BEGIN_NV04(push, NV30_3D(QUERY_GET), 1); PUSH_DATA (push, (q->report << 24) | q->qo[1]->hw->start); } if (q->enable) { BEGIN_NV04(push, SUBC_3D(q->enable), 1); PUSH_DATA (push, 0); } PUSH_KICK (push); }
static void nvc0_emit_string_marker(struct pipe_context *pipe, const char *str, int len) { struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf; int string_words = len / 4; int data_words; if (len <= 0) return; string_words = MIN2(string_words, NV04_PFIFO_MAX_PACKET_LEN); if (string_words == NV04_PFIFO_MAX_PACKET_LEN) data_words = string_words; else data_words = string_words + !!(len & 3); BEGIN_NIC0(push, SUBC_3D(NV04_GRAPH_NOP), data_words); if (string_words) PUSH_DATAp(push, str, string_words); if (string_words != data_words) { int data = 0; memcpy(&data, &str[string_words * 4], len & 3); PUSH_DATA (push, data); } }
static void nv50_screen_init_hwctx(struct nv50_screen *screen) { struct nouveau_pushbuf *push = screen->base.pushbuf; struct nv04_fifo *fifo; unsigned i; fifo = (struct nv04_fifo *)screen->base.channel->data; BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1); PUSH_DATA (push, screen->m2mf->handle); BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3); PUSH_DATA (push, screen->sync->handle); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1); PUSH_DATA (push, screen->eng2d->handle); BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4); PUSH_DATA (push, screen->sync->handle); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, NV50_2D(OPERATION), 1); PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY); BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_2D(0x0888), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1); PUSH_DATA (push, screen->tesla->handle); BEGIN_NV04(push, NV50_3D(COND_MODE), 1); PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1); PUSH_DATA (push, screen->sync->handle); BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11); for (i = 0; i < 11; ++i) PUSH_DATA(push, fifo->vram); BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN); for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i) PUSH_DATA(push, fifo->vram); BEGIN_NV04(push, NV50_3D(REG_MODE), 1); PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED); BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1); PUSH_DATA (push, 0xf); if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) { BEGIN_NV04(push, NV50_3D(WATCHDOG_TIMER), 1); PUSH_DATA (push, 0x18); } BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1); PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1); BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1); PUSH_DATA (push, 1); if (screen->tesla->oclass >= NVA0_3D_CLASS) { BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1); PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); } BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1); PUSH_DATA (push, 0x3f); BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2); PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2)); BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2); PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2)); BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2); PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2)); BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->tls_bo->offset); PUSH_DATA (push, screen->tls_bo->offset); PUSH_DATA (push, util_logbase2(screen->cur_tls_space / 8)); BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->stack_bo->offset); PUSH_DATA (push, screen->stack_bo->offset); PUSH_DATA (push, 4); BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->uniforms->offset + (0 << 16)); PUSH_DATA (push, screen->uniforms->offset + (0 << 16)); PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000); BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->uniforms->offset + (1 << 16)); PUSH_DATA (push, screen->uniforms->offset + (1 << 16)); PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000); BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->uniforms->offset + (2 << 16)); PUSH_DATA (push, screen->uniforms->offset + (2 << 16)); PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000); BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->uniforms->offset + (3 << 16)); PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); /* return { 0.0, 0.0, 0.0, 0.0 } on out-of-bounds vtxbuf access */ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); PUSH_DATA (push, ((1 << 9) << 6) | NV50_CB_AUX); BEGIN_NI04(push, NV50_3D(CB_DATA(0)), 4); PUSH_DATAf(push, 0.0f); PUSH_DATAf(push, 0.0f); PUSH_DATAf(push, 0.0f); PUSH_DATAf(push, 0.0f); BEGIN_NV04(push, NV50_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); PUSH_DATAh(push, screen->uniforms->offset + (3 << 16) + (1 << 9)); PUSH_DATA (push, screen->uniforms->offset + (3 << 16) + (1 << 9)); /* max TIC (bits 4:8) & TSC bindings, per program type */ for (i = 0; i < 3; ++i) { BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1); PUSH_DATA (push, 0x54); } BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->txc->offset); PUSH_DATA (push, screen->txc->offset); PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1); BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3); PUSH_DATAh(push, screen->txc->offset + 65536); PUSH_DATA (push, screen->txc->offset + 65536); PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1); BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1); PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY); BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2); for (i = 0; i < 8 * 2; ++i) PUSH_DATA(push, 0); BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2); PUSH_DATAf(push, 0.0f); PUSH_DATAf(push, 1.0f); BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1); #ifdef NV50_SCISSORS_CLIPPING PUSH_DATA (push, 0x0000); #else PUSH_DATA (push, 0x1080); #endif BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1); PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); /* We use scissors instead of exact view volume clipping, * so they're always enabled. */ BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3); PUSH_DATA (push, 1); PUSH_DATA (push, 8192 << 16); PUSH_DATA (push, 8192 << 16); BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1); PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL); BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1); PUSH_DATA (push, 0x11111111); BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1); PUSH_DATA (push, 1); PUSH_KICK (push); }
static void nv50_render_condition(struct pipe_context *pipe, struct pipe_query *pq, boolean condition, uint mode) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q; uint32_t cond; boolean wait = mode != PIPE_RENDER_COND_NO_WAIT && mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT; if (!pq) { cond = NV50_3D_COND_MODE_ALWAYS; } else { q = nv50_query(pq); /* NOTE: comparison of 2 queries only works if both have completed */ switch (q->type) { case PIPE_QUERY_SO_OVERFLOW_PREDICATE: cond = condition ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_NOT_EQUAL; wait = TRUE; break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: if (likely(!condition)) { /* XXX: Placeholder, handle nesting here if available */ if (unlikely(false)) cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL : NV50_3D_COND_MODE_ALWAYS; else cond = NV50_3D_COND_MODE_RES_NON_ZERO; } else { cond = wait ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_ALWAYS; } break; default: assert(!"render condition query not a predicate"); cond = NV50_3D_COND_MODE_ALWAYS; break; } } nv50->cond_query = pq; nv50->cond_cond = condition; nv50->cond_condmode = cond; nv50->cond_mode = mode; if (!pq) { PUSH_SPACE(push, 2); BEGIN_NV04(push, NV50_3D(COND_MODE), 1); PUSH_DATA (push, cond); return; } PUSH_SPACE(push, 9); if (wait) { BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); PUSH_DATA (push, 0); } PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3); PUSH_DATAh(push, q->bo->offset + q->offset); PUSH_DATA (push, q->bo->offset + q->offset); PUSH_DATA (push, cond); BEGIN_NV04(push, NV50_2D(COND_ADDRESS_HIGH), 2); PUSH_DATAh(push, q->bo->offset + q->offset); PUSH_DATA (push, q->bo->offset + q->offset); }
static void nv20_hwctx_init(struct gl_context *ctx) { struct nouveau_pushbuf *push = context_push(ctx); struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; struct nv04_fifo *fifo = hw->chan->data; int i; BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); PUSH_DATA (push, hw->eng3d->handle); BEGIN_NV04(push, NV20_3D(DMA_NOTIFY), 1); PUSH_DATA (push, hw->ntfy->handle); BEGIN_NV04(push, NV20_3D(DMA_TEXTURE0), 2); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->gart); BEGIN_NV04(push, NV20_3D(DMA_COLOR), 2); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, NV20_3D(DMA_VTXBUF0), 2); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->gart); BEGIN_NV04(push, NV20_3D(DMA_QUERY), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RT_HORIZ), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_HORIZ(0)), 1); PUSH_DATA (push, 0xfff << 16 | 0x0); BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_VERT(0)), 1); PUSH_DATA (push, 0xfff << 16 | 0x0); for (i = 1; i < NV20_3D_VIEWPORT_CLIP_HORIZ__LEN; i++) { BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_HORIZ(i)), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_VERT(i)), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV20_3D(VIEWPORT_CLIP_MODE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_3D(0x17e0), 3); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); if (context_chipset(ctx) >= 0x25) { BEGIN_NV04(push, NV20_3D(TEX_RCOMP), 1); PUSH_DATA (push, NV20_3D_TEX_RCOMP_LEQUAL | 0xdb0); } else { BEGIN_NV04(push, SUBC_3D(0x1e68), 1); PUSH_DATA (push, 0x4b800000); /* 16777216.000000 */ BEGIN_NV04(push, NV20_3D(TEX_RCOMP), 1); PUSH_DATA (push, NV20_3D_TEX_RCOMP_LEQUAL); } BEGIN_NV04(push, SUBC_3D(0x290), 1); PUSH_DATA (push, 0x10 << 16 | 1); BEGIN_NV04(push, SUBC_3D(0x9fc), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_3D(0x1d80), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, SUBC_3D(0x9f8), 1); PUSH_DATA (push, 4); BEGIN_NV04(push, SUBC_3D(0x17ec), 3); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); if (context_chipset(ctx) >= 0x25) { BEGIN_NV04(push, SUBC_3D(0x1d88), 1); PUSH_DATA (push, 3); BEGIN_NV04(push, NV25_3D(DMA_HIERZ), 1); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, NV25_3D(UNK01AC), 1); PUSH_DATA (push, fifo->vram); } BEGIN_NV04(push, NV20_3D(DMA_FENCE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_3D(0x1e98), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV04_GRAPH(3D, NOTIFY), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_3D(0x120), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 1); PUSH_DATA (push, 2); if (context_chipset(ctx) >= 0x25) { BEGIN_NV04(push, SUBC_3D(0x1da4), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV20_3D(RT_HORIZ), 2); PUSH_DATA (push, 0 << 16 | 0); PUSH_DATA (push, 0 << 16 | 0); BEGIN_NV04(push, NV20_3D(ALPHA_FUNC_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(ALPHA_FUNC_FUNC), 2); PUSH_DATA (push, NV20_3D_ALPHA_FUNC_FUNC_ALWAYS); PUSH_DATA (push, 0); for (i = 0; i < NV20_3D_TEX__LEN; i++) { BEGIN_NV04(push, NV20_3D(TEX_ENABLE(i)), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV20_3D(TEX_SHADER_OP), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(TEX_SHADER_CULL_MODE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_IN_ALPHA(0)), 4); PUSH_DATA (push, 0x30d410d0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_OUT_RGB(0)), 4); PUSH_DATA (push, 0x00000c00); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_ENABLE), 1); PUSH_DATA (push, 0x00011101); BEGIN_NV04(push, NV20_3D(RC_FINAL0), 2); PUSH_DATA (push, 0x130e0300); PUSH_DATA (push, 0x0c091c80); BEGIN_NV04(push, NV20_3D(RC_OUT_ALPHA(0)), 4); PUSH_DATA (push, 0x00000c00); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_IN_RGB(0)), 4); PUSH_DATA (push, 0x20c400c0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_COLOR0), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(RC_CONSTANT_COLOR0(0)), 4); PUSH_DATA (push, 0x035125a0); PUSH_DATA (push, 0); PUSH_DATA (push, 0x40002000); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(MULTISAMPLE_CONTROL), 1); PUSH_DATA (push, 0xffff0000); BEGIN_NV04(push, NV20_3D(BLEND_FUNC_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(DITHER_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(STENCIL_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(BLEND_FUNC_SRC), 4); PUSH_DATA (push, NV20_3D_BLEND_FUNC_SRC_ONE); PUSH_DATA (push, NV20_3D_BLEND_FUNC_DST_ZERO); PUSH_DATA (push, 0); PUSH_DATA (push, NV20_3D_BLEND_EQUATION_FUNC_ADD); BEGIN_NV04(push, NV20_3D(STENCIL_MASK), 7); PUSH_DATA (push, 0xff); PUSH_DATA (push, NV20_3D_STENCIL_FUNC_FUNC_ALWAYS); PUSH_DATA (push, 0); PUSH_DATA (push, 0xff); PUSH_DATA (push, NV20_3D_STENCIL_OP_FAIL_KEEP); PUSH_DATA (push, NV20_3D_STENCIL_OP_ZFAIL_KEEP); PUSH_DATA (push, NV20_3D_STENCIL_OP_ZPASS_KEEP); BEGIN_NV04(push, NV20_3D(COLOR_LOGIC_OP_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, NV20_3D_COLOR_LOGIC_OP_OP_COPY); BEGIN_NV04(push, SUBC_3D(0x17cc), 1); PUSH_DATA (push, 0); if (context_chipset(ctx) >= 0x25) { BEGIN_NV04(push, SUBC_3D(0x1d84), 1); PUSH_DATA (push, 1); } BEGIN_NV04(push, NV20_3D(LIGHTING_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(LIGHT_MODEL), 1); PUSH_DATA (push, NV20_3D_LIGHT_MODEL_VIEWER_NONLOCAL); BEGIN_NV04(push, NV20_3D(SEPARATE_SPECULAR_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(LIGHT_MODEL_TWO_SIDE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(ENABLED_LIGHTS), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(NORMALIZE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(POLYGON_STIPPLE_PATTERN(0)), NV20_3D_POLYGON_STIPPLE_PATTERN__LEN); for (i = 0; i < NV20_3D_POLYGON_STIPPLE_PATTERN__LEN; i++) { PUSH_DATA (push, 0xffffffff); } BEGIN_NV04(push, NV20_3D(POLYGON_OFFSET_POINT_ENABLE), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(DEPTH_FUNC), 1); PUSH_DATA (push, NV20_3D_DEPTH_FUNC_LESS); BEGIN_NV04(push, NV20_3D(DEPTH_WRITE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(DEPTH_TEST_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(POLYGON_OFFSET_FACTOR), 2); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); BEGIN_NV04(push, NV20_3D(DEPTH_CLAMP), 1); PUSH_DATA (push, 1); if (context_chipset(ctx) < 0x25) { BEGIN_NV04(push, SUBC_3D(0x1d84), 1); PUSH_DATA (push, 3); } BEGIN_NV04(push, NV20_3D(POINT_SIZE), 1); if (context_chipset(ctx) >= 0x25) PUSH_DATAf(push, 1.0); else PUSH_DATA (push, 8); if (context_chipset(ctx) >= 0x25) { BEGIN_NV04(push, NV20_3D(POINT_PARAMETERS_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, SUBC_3D(0x0a1c), 1); PUSH_DATA (push, 0x800); } else { BEGIN_NV04(push, NV20_3D(POINT_PARAMETERS_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV20_3D(LINE_WIDTH), 1); PUSH_DATA (push, 8); BEGIN_NV04(push, NV20_3D(LINE_SMOOTH_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(POLYGON_MODE_FRONT), 2); PUSH_DATA (push, NV20_3D_POLYGON_MODE_FRONT_FILL); PUSH_DATA (push, NV20_3D_POLYGON_MODE_BACK_FILL); BEGIN_NV04(push, NV20_3D(CULL_FACE), 2); PUSH_DATA (push, NV20_3D_CULL_FACE_BACK); PUSH_DATA (push, NV20_3D_FRONT_FACE_CCW); BEGIN_NV04(push, NV20_3D(POLYGON_SMOOTH_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(CULL_FACE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(SHADE_MODEL), 1); PUSH_DATA (push, NV20_3D_SHADE_MODEL_SMOOTH); BEGIN_NV04(push, NV20_3D(POLYGON_STIPPLE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(TEX_GEN_MODE(0,0)), 4 * NV20_3D_TEX_GEN_MODE__ESIZE); for (i=0; i < 4 * NV20_3D_TEX_GEN_MODE__LEN; i++) PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(FOG_COEFF(0)), 3); PUSH_DATAf(push, 1.5); PUSH_DATAf(push, -0.090168); PUSH_DATAf(push, 0.0); BEGIN_NV04(push, NV20_3D(FOG_MODE), 2); PUSH_DATA (push, NV20_3D_FOG_MODE_EXP_SIGNED); PUSH_DATA (push, NV20_3D_FOG_COORD_FOG); BEGIN_NV04(push, NV20_3D(FOG_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(ENGINE), 1); PUSH_DATA (push, NV20_3D_ENGINE_FIXED); for (i = 0; i < NV20_3D_TEX_MATRIX_ENABLE__LEN; i++) { BEGIN_NV04(push, NV20_3D(TEX_MATRIX_ENABLE(i)), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV20_3D(VERTEX_ATTR_4F_X(1)), 4 * 15); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); for (i = 0; i < 12; i++) { PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); } BEGIN_NV04(push, NV20_3D(EDGEFLAG_ENABLE), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV20_3D(COLOR_MASK), 1); PUSH_DATA (push, 0x00010101); BEGIN_NV04(push, NV20_3D(CLEAR_VALUE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV20_3D(DEPTH_RANGE_NEAR), 2); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 16777216.0); BEGIN_NV04(push, NV20_3D(VIEWPORT_TRANSLATE_X), 4); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 16777215.0); BEGIN_NV04(push, NV20_3D(VIEWPORT_SCALE_X), 4); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 16777215.0 * 0.5); PUSH_DATAf(push, 65535.0); PUSH_KICK (push); }
void nvc0_fragprog_validate(struct nvc0_context *nvc0) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_program *fp = nvc0->fragprog; struct pipe_rasterizer_state *rast = &nvc0->rast->pipe; if (fp->fp.force_persample_interp != rast->force_persample_interp) { /* Force the program to be reuploaded, which will trigger interp fixups * to get applied */ if (fp->mem) nouveau_heap_free(&fp->mem); fp->fp.force_persample_interp = rast->force_persample_interp; } /* Shade model works well enough when both colors follow it. However if one * (or both) is explicitly set, then we have to go the patching route. */ bool has_explicit_color = fp->fp.colors && (((fp->fp.colors & 1) && !fp->fp.color_interp[0]) || ((fp->fp.colors & 2) && !fp->fp.color_interp[1])); bool hwflatshade = false; if (has_explicit_color && fp->fp.flatshade != rast->flatshade) { /* Force re-upload */ if (fp->mem) nouveau_heap_free(&fp->mem); fp->fp.flatshade = rast->flatshade; /* Always smooth-shade in this mode, the shader will decide on its own * when to flat-shade. */ } else if (!has_explicit_color) { hwflatshade = rast->flatshade; /* No need to binary-patch the shader each time, make sure that it's set * up for the default behaviour. */ fp->fp.flatshade = 0; } if (hwflatshade != nvc0->state.flatshade) { nvc0->state.flatshade = hwflatshade; BEGIN_NVC0(push, NVC0_3D(SHADE_MODEL), 1); PUSH_DATA (push, hwflatshade ? NVC0_3D_SHADE_MODEL_FLAT : NVC0_3D_SHADE_MODEL_SMOOTH); } if (fp->mem && !(nvc0->dirty_3d & NVC0_NEW_3D_FRAGPROG)) { return; } if (!nvc0_program_validate(nvc0, fp)) return; nvc0_program_update_context_state(nvc0, fp, 4); if (fp->fp.early_z != nvc0->state.early_z_forced) { nvc0->state.early_z_forced = fp->fp.early_z; IMMED_NVC0(push, NVC0_3D(FORCE_EARLY_FRAGMENT_TESTS), fp->fp.early_z); } BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2); PUSH_DATA (push, 0x51); PUSH_DATA (push, fp->code_base); BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1); PUSH_DATA (push, fp->num_gprs); BEGIN_NVC0(push, SUBC_3D(0x0360), 2); PUSH_DATA (push, 0x20164010); PUSH_DATA (push, 0x20); BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1); PUSH_DATA (push, fp->flags[0]); }
static void nv30_transfer_rect_blit(XFER_ARGS) { struct nv04_resource *fp = nv30_transfer_rect_fragprog(nv30); struct nouveau_heap *vp = nv30_transfer_rect_vertprog(nv30); struct nouveau_pushbuf *push = nv30->base.pushbuf; struct nouveau_pushbuf_refn refs[] = { { fp->bo, fp->domain | NOUVEAU_BO_RD }, { src->bo, src->domain | NOUVEAU_BO_RD }, { dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR }, }; u32 texfmt, texswz; u32 format, stride; if (nouveau_pushbuf_space(push, 512, 8, 0) || nouveau_pushbuf_refn (push, refs, sizeof(refs) / sizeof(refs[0]))) return; /* various switches depending on cpp of the transfer */ switch (dst->cpp) { case 4: format = NV30_3D_RT_FORMAT_COLOR_A8R8G8B8 | NV30_3D_RT_FORMAT_ZETA_Z24S8; texfmt = NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8; texswz = 0x0000aae4; break; case 2: format = NV30_3D_RT_FORMAT_COLOR_R5G6B5 | NV30_3D_RT_FORMAT_ZETA_Z16; texfmt = NV40_3D_TEX_FORMAT_FORMAT_R5G6B5; texswz = 0x0000a9e4; break; case 1: format = NV30_3D_RT_FORMAT_COLOR_B8 | NV30_3D_RT_FORMAT_ZETA_Z16; texfmt = NV40_3D_TEX_FORMAT_FORMAT_L8; texswz = 0x0000aaff; break; default: assert(0); return; } /* render target */ if (!dst->pitch) { format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED; format |= util_logbase2(dst->w) << 16; format |= util_logbase2(dst->h) << 24; stride = 64; } else { format |= NV30_3D_RT_FORMAT_TYPE_LINEAR; stride = dst->pitch; } BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2); PUSH_DATA (push, dst->w << 16); PUSH_DATA (push, dst->h << 16); BEGIN_NV04(push, NV30_3D(RT_HORIZ), 5); PUSH_DATA (push, dst->w << 16); PUSH_DATA (push, dst->h << 16); PUSH_DATA (push, format); PUSH_DATA (push, stride); PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1); PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0); nv30->dirty |= NV30_NEW_FRAMEBUFFER; /* viewport state */ BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 1.0); BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); nv30->dirty |= NV30_NEW_VIEWPORT; /* blend state */ BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1); PUSH_DATA (push, 0x01010101); nv30->dirty |= NV30_NEW_BLEND; /* depth-stencil-alpha state */ BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1); PUSH_DATA (push, 0); nv30->dirty |= NV30_NEW_ZSA; /* rasterizer state */ BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1); PUSH_DATA (push, NV30_3D_SHADE_MODEL_FLAT); BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2); PUSH_DATA (push, NV30_3D_POLYGON_MODE_FRONT_FILL); PUSH_DATA (push, NV30_3D_POLYGON_MODE_BACK_FILL); BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FILL_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_ENABLE), 1); PUSH_DATA (push, 0); nv30->state.scissor_off = 0; nv30->dirty |= NV30_NEW_RASTERIZER; /* vertex program */ BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1); PUSH_DATA (push, vp->start); BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2); PUSH_DATA (push, 0x00000101); /* attrib: 0, 8 */ PUSH_DATA (push, 0x00004000); /* result: hpos, tex0 */ BEGIN_NV04(push, NV30_3D(ENGINE), 1); PUSH_DATA (push, 0x00000103); BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1); PUSH_DATA (push, 0x00000000); nv30->dirty |= NV30_NEW_VERTPROG; nv30->dirty |= NV30_NEW_CLIP; /* fragment program */ BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1); PUSH_RELOC(push, fp->bo, fp->offset, fp->domain | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV30_3D_FP_ACTIVE_PROGRAM_DMA0, NV30_3D_FP_ACTIVE_PROGRAM_DMA1); BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1); PUSH_DATA (push, 0x02000000); nv30->state.fragprog = NULL; nv30->dirty |= NV30_NEW_FRAGPROG; /* texture */ texfmt |= 1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT; texfmt |= NV30_3D_TEX_FORMAT_NO_BORDER; texfmt |= NV40_3D_TEX_FORMAT_RECT; texfmt |= 0x00008000; if (src->d < 2) texfmt |= NV30_3D_TEX_FORMAT_DIMS_2D; else texfmt |= NV30_3D_TEX_FORMAT_DIMS_3D; if (src->pitch) texfmt |= NV40_3D_TEX_FORMAT_LINEAR; BEGIN_NV04(push, NV30_3D(TEX_OFFSET(0)), 8); PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0); PUSH_RELOC(push, src->bo, texfmt, NOUVEAU_BO_OR, NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1); PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE | NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE); PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE); PUSH_DATA (push, texswz); switch (filter) { case BILINEAR: PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR | NV30_3D_TEX_FILTER_MAG_LINEAR | 0x00002000); break; default: PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST | NV30_3D_TEX_FILTER_MAG_NEAREST | 0x00002000); break; } PUSH_DATA (push, (src->w << 16) | src->h); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV40_3D(TEX_SIZE1(0)), 1); PUSH_DATA (push, 0x00100000 | src->pitch); BEGIN_NV04(push, SUBC_3D(0x0b40), 1); PUSH_DATA (push, src->d < 2 ? 0x00000001 : 0x00000000); BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1); PUSH_DATA (push, 1); nv30->fragprog.dirty_samplers |= 1; nv30->dirty |= NV30_NEW_FRAGTEX; /* blit! */ BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); PUSH_DATA (push, (dst->x1 - dst->x0) << 16 | dst->x0); PUSH_DATA (push, (dst->y1 - dst->y0) << 16 | dst->y0); BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_QUADS); BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3); PUSH_DATAf(push, src->x0); PUSH_DATAf(push, src->y0); PUSH_DATAf(push, src->z); BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); PUSH_DATA (push, (dst->y0 << 16) | dst->x0); BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3); PUSH_DATAf(push, src->x1); PUSH_DATAf(push, src->y0); PUSH_DATAf(push, src->z); BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); PUSH_DATA (push, (dst->y0 << 16) | dst->x1); BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3); PUSH_DATAf(push, src->x1); PUSH_DATAf(push, src->y1); PUSH_DATAf(push, src->z); BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); PUSH_DATA (push, (dst->y1 << 16) | dst->x1); BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3); PUSH_DATAf(push, src->x0); PUSH_DATAf(push, src->y1); PUSH_DATAf(push, src->z); BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1); PUSH_DATA (push, (dst->y1 << 16) | dst->x0); BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1); PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP); }
static void nv50_render_condition(struct pipe_context *pipe, struct pipe_query *pq, boolean condition, enum pipe_render_cond_flag mode) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; struct nv50_query *q = nv50_query(pq); struct nv50_hw_query *hq = nv50_hw_query(q); uint32_t cond; bool wait = mode != PIPE_RENDER_COND_NO_WAIT && mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT; if (!pq) { cond = NV50_3D_COND_MODE_ALWAYS; } else { /* NOTE: comparison of 2 queries only works if both have completed */ switch (q->type) { case PIPE_QUERY_SO_OVERFLOW_PREDICATE: cond = condition ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_NOT_EQUAL; wait = true; break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (hq->state == NV50_HW_QUERY_STATE_READY) wait = true; if (likely(!condition)) { cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL : NV50_3D_COND_MODE_ALWAYS; } else { cond = wait ? NV50_3D_COND_MODE_EQUAL : NV50_3D_COND_MODE_ALWAYS; } break; default: assert(!"render condition query not a predicate"); cond = NV50_3D_COND_MODE_ALWAYS; break; } } nv50->cond_query = pq; nv50->cond_cond = condition; nv50->cond_condmode = cond; nv50->cond_mode = mode; if (!pq) { PUSH_SPACE(push, 2); BEGIN_NV04(push, NV50_3D(COND_MODE), 1); PUSH_DATA (push, cond); return; } PUSH_SPACE(push, 9); if (wait && hq->state != NV50_HW_QUERY_STATE_READY) { BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1); PUSH_DATA (push, 0); } PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3); PUSH_DATAh(push, hq->bo->offset + hq->offset); PUSH_DATA (push, hq->bo->offset + hq->offset); PUSH_DATA (push, cond); BEGIN_NV04(push, NV50_2D(COND_ADDRESS_HIGH), 2); PUSH_DATAh(push, hq->bo->offset + hq->offset); PUSH_DATA (push, hq->bo->offset + hq->offset); }
static void nv10_hwctx_init(struct gl_context *ctx) { struct nouveau_pushbuf *push = context_push(ctx); struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; struct nv04_fifo *fifo = hw->chan->data; int i; BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); PUSH_DATA (push, hw->eng3d->handle); BEGIN_NV04(push, NV10_3D(DMA_NOTIFY), 1); PUSH_DATA (push, hw->ntfy->handle); BEGIN_NV04(push, NV10_3D(DMA_TEXTURE0), 3); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->gart); PUSH_DATA (push, fifo->gart); BEGIN_NV04(push, NV10_3D(DMA_COLOR), 2); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(RT_HORIZ), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1); PUSH_DATA (push, 0x7ff << 16 | 0x800); BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1); PUSH_DATA (push, 0x7ff << 16 | 0x800); for (i = 1; i < 8; i++) { BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(i)), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(i)), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, SUBC_3D(0x290), 1); PUSH_DATA (push, 0x10 << 16 | 1); BEGIN_NV04(push, SUBC_3D(0x3f4), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); PUSH_DATA (push, 0); if (context_chipset(ctx) >= 0x17) { BEGIN_NV04(push, NV17_3D(UNK01AC), 2); PUSH_DATA (push, fifo->vram); PUSH_DATA (push, fifo->vram); BEGIN_NV04(push, SUBC_3D(0xd84), 1); PUSH_DATA (push, 0x3); BEGIN_NV04(push, NV17_3D(COLOR_MASK_ENABLE), 1); PUSH_DATA (push, 1); } if (context_chipset(ctx) >= 0x11) { BEGIN_NV04(push, SUBC_3D(0x120), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 1); PUSH_DATA (push, 2); BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); PUSH_DATA (push, 0); } BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); PUSH_DATA (push, 0); /* Set state */ BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_FUNC), 2); PUSH_DATA (push, 0x207); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(TEX_ENABLE(0)), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(DITHER_ENABLE), 2); PUSH_DATA (push, 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(VERTEX_WEIGHT_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 4); PUSH_DATA (push, 1); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0x8006); BEGIN_NV04(push, NV10_3D(STENCIL_MASK), 8); PUSH_DATA (push, 0xff); PUSH_DATA (push, 0x207); PUSH_DATA (push, 0); PUSH_DATA (push, 0xff); PUSH_DATA (push, 0x1e00); PUSH_DATA (push, 0x1e00); PUSH_DATA (push, 0x1e00); PUSH_DATA (push, 0x1d01); BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_POINT_ENABLE), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(DEPTH_FUNC), 1); PUSH_DATA (push, 0x201); BEGIN_NV04(push, NV10_3D(DEPTH_WRITE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(DEPTH_TEST_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_FACTOR), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(POINT_SIZE), 1); PUSH_DATA (push, 8); BEGIN_NV04(push, NV10_3D(POINT_PARAMETERS_ENABLE), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(LINE_WIDTH), 1); PUSH_DATA (push, 8); BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(POLYGON_MODE_FRONT), 2); PUSH_DATA (push, 0x1b02); PUSH_DATA (push, 0x1b02); BEGIN_NV04(push, NV10_3D(CULL_FACE), 2); PUSH_DATA (push, 0x405); PUSH_DATA (push, 0x901); BEGIN_NV04(push, NV10_3D(POLYGON_SMOOTH_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(CULL_FACE_ENABLE), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(TEX_GEN_MODE(0, 0)), 8); for (i = 0; i < 8; i++) PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(0)), 2); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3); PUSH_DATA (push, 0x3fc00000); /* -1.50 */ PUSH_DATA (push, 0xbdb8aa0a); /* -0.09 */ PUSH_DATA (push, 0); /* 0.00 */ BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(FOG_MODE), 2); PUSH_DATA (push, 0x802); PUSH_DATA (push, 2); /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when * using texturing, except when using the texture matrix */ BEGIN_NV04(push, NV10_3D(VIEW_MATRIX_ENABLE), 1); PUSH_DATA (push, 6); BEGIN_NV04(push, NV10_3D(COLOR_MASK), 1); PUSH_DATA (push, 0x01010101); /* Set vertex component */ BEGIN_NV04(push, NV10_3D(VERTEX_COL_4F_R), 4); PUSH_DATAf(push, 1.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); BEGIN_NV04(push, NV10_3D(VERTEX_COL2_3F_R), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV10_3D(VERTEX_NOR_3F_X), 3); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATAf(push, 1.0); BEGIN_NV04(push, NV10_3D(VERTEX_TX0_4F_S), 4); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); BEGIN_NV04(push, NV10_3D(VERTEX_TX1_4F_S), 4); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 1.0); BEGIN_NV04(push, NV10_3D(VERTEX_FOG_1F), 1); PUSH_DATAf(push, 0.0); BEGIN_NV04(push, NV10_3D(EDGEFLAG_ENABLE), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV10_3D(DEPTH_RANGE_NEAR), 2); PUSH_DATAf(push, 0.0); PUSH_DATAf(push, 16777216.0); PUSH_KICK (push); }
void nv30_fragprog_validate(struct nv30_context *nv30) { struct nouveau_pushbuf *push = nv30->base.pushbuf; struct nouveau_object *eng3d = nv30->screen->eng3d; struct nv30_fragprog *fp = nv30->fragprog.program; bool upload = false; int i; if (!fp->translated) { _nvfx_fragprog_translate(eng3d->oclass, fp); if (!fp->translated) return; upload = true; } /* update constants, also needs to be done on every fp switch as we * have no idea whether the constbuf changed in the meantime */ if (nv30->fragprog.constbuf) { struct pipe_resource *constbuf = nv30->fragprog.constbuf; uint32_t *cbuf = (uint32_t *)nv04_resource(constbuf)->data; for (i = 0; i < fp->nr_consts; i++) { unsigned off = fp->consts[i].offset; unsigned idx = fp->consts[i].index * 4; if (!memcmp(&fp->insn[off], &cbuf[idx], 4 * 4)) continue; memcpy(&fp->insn[off], &cbuf[idx], 4 * 4); upload = true; } } if (upload) nv30_fragprog_upload(nv30); /* FP_ACTIVE_PROGRAM needs to be done again even if only the consts * were updated. TEX_CACHE_CTL magic is not enough to convince the * GPU that it should re-read the fragprog from VRAM... sigh. */ if (nv30->state.fragprog != fp || upload) { struct nv04_resource *r = nv04_resource(fp->buffer); if (!PUSH_SPACE(push, 8)) return; PUSH_RESET(push, BUFCTX_FRAGPROG); BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1); PUSH_RESRC(push, NV30_3D(FP_ACTIVE_PROGRAM), BUFCTX_FRAGPROG, r, 0, NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_OR, NV30_3D_FP_ACTIVE_PROGRAM_DMA0, NV30_3D_FP_ACTIVE_PROGRAM_DMA1); BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1); PUSH_DATA (push, fp->fp_control); if (eng3d->oclass < NV40_3D_CLASS) { BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1); PUSH_DATA (push, 0x00010004); BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1); PUSH_DATA (push, fp->texcoords); } else { BEGIN_NV04(push, SUBC_3D(0x0b40), 1); PUSH_DATA (push, 0x00000000); } nv30->state.fragprog = fp; } }