static void r600_flush_vgt_streamout(struct r600_common_context *rctx) { struct radeon_winsys_cs *cs = rctx->rings.gfx.cs; unsigned reg_strmout_cntl; /* The register is at different places on different ASICs. */ if (rctx->chip_class >= CIK) { reg_strmout_cntl = R_0300FC_CP_STRMOUT_CNTL; } else if (rctx->chip_class >= EVERGREEN) { reg_strmout_cntl = R_0084FC_CP_STRMOUT_CNTL; } else { reg_strmout_cntl = R_008490_CP_STRMOUT_CNTL; } if (rctx->chip_class >= CIK) { cik_write_uconfig_reg(cs, reg_strmout_cntl, 0); } else { r600_write_config_reg(cs, reg_strmout_cntl, 0); } radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_SO_VGTSTREAMOUT_FLUSH) | EVENT_INDEX(0)); radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0)); radeon_emit(cs, WAIT_REG_MEM_EQUAL); /* wait until the register is equal to the reference value */ radeon_emit(cs, reg_strmout_cntl >> 2); /* register */ radeon_emit(cs, 0); radeon_emit(cs, S_008490_OFFSET_UPDATE_DONE(1)); /* reference value */ radeon_emit(cs, S_008490_OFFSET_UPDATE_DONE(1)); /* mask */ radeon_emit(cs, 4); /* poll interval */ }
static inline void evergreen_context_ps_partial_flush(struct r600_context *ctx) { struct radeon_winsys_cs *cs = ctx->cs; if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING)) return; cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); ctx->flags &= ~R600_CONTEXT_DRAW_PENDING; }
void evergreen_flush_vgt_streamout(struct r600_context *ctx) { struct radeon_winsys_cs *cs = ctx->rings.gfx.cs; r600_write_config_reg(cs, R_0084FC_CP_STRMOUT_CNTL, 0); cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SO_VGTSTREAMOUT_FLUSH) | EVENT_INDEX(0); cs->buf[cs->cdw++] = PKT3(PKT3_WAIT_REG_MEM, 5, 0); cs->buf[cs->cdw++] = WAIT_REG_MEM_EQUAL; /* wait until the register is equal to the reference value */ cs->buf[cs->cdw++] = R_0084FC_CP_STRMOUT_CNTL >> 2; /* register */ cs->buf[cs->cdw++] = 0; cs->buf[cs->cdw++] = S_0084FC_OFFSET_UPDATE_DONE(1); /* reference value */ cs->buf[cs->cdw++] = S_0084FC_OFFSET_UPDATE_DONE(1); /* mask */ cs->buf[cs->cdw++] = 4; /* poll interval */ }
int weston_wm_handle_dnd_event(struct weston_wm *wm, xcb_generic_event_t *event) { xcb_xfixes_selection_notify_event_t *xfixes_selection_notify = (xcb_xfixes_selection_notify_event_t *) event; xcb_client_message_event_t *client_message = (xcb_client_message_event_t *) event; switch (event->response_type - wm->xfixes->first_event) { case XCB_XFIXES_SELECTION_NOTIFY: if (xfixes_selection_notify->selection != wm->atom.xdnd_selection) return 0; weston_log("XdndSelection owner: %d!\n", xfixes_selection_notify->owner); if (xfixes_selection_notify->owner != XCB_WINDOW_NONE) weston_dnd_start(wm, xfixes_selection_notify->owner); else weston_dnd_stop(wm); return 1; } switch (EVENT_TYPE(event)) { case XCB_CLIENT_MESSAGE: if (client_message->type == wm->atom.xdnd_enter) { handle_enter(wm, client_message); return 1; } else if (client_message->type == wm->atom.xdnd_leave) { weston_log("got leave!\n"); return 1; } else if (client_message->type == wm->atom.xdnd_drop) { weston_log("got drop!\n"); return 1; } else if (client_message->type == wm->atom.xdnd_drop) { weston_log("got enter!\n"); return 1; } return 0; } return 0; }
/* * CP. */ void cayman_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { struct radeon_ring *ring = &rdev->ring[fence->ring]; u64 addr = rdev->fence_drv[fence->ring].gpu_addr; /* flush read cache over gart for this vmid */ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); radeon_ring_write(ring, 0); radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); radeon_ring_write(ring, 0xFFFFFFFF); radeon_ring_write(ring, 0); radeon_ring_write(ring, 10); /* poll interval */ /* EVENT_WRITE_EOP - flush caches, send int */ radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); radeon_ring_write(ring, addr & 0xffffffff); radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); radeon_ring_write(ring, fence->seq); radeon_ring_write(ring, 0); }
/** * Write an EOP event. * * \param event EVENT_TYPE_* * \param event_flags Optional cache flush flags (TC) * \param data_sel 1 = fence, 3 = timestamp * \param buf Buffer * \param va GPU address * \param old_value Previous fence value (for a bug workaround) * \param new_value Fence value to write for this event. */ void r600_gfx_write_event_eop(struct r600_common_context *ctx, unsigned event, unsigned event_flags, unsigned data_sel, struct r600_resource *buf, uint64_t va, uint32_t new_fence, unsigned query_type) { struct radeon_winsys_cs *cs = ctx->gfx.cs; unsigned op = EVENT_TYPE(event) | EVENT_INDEX(5) | event_flags; unsigned sel = EOP_DATA_SEL(data_sel); radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0)); radeon_emit(cs, op); radeon_emit(cs, va); radeon_emit(cs, ((va >> 32) & 0xffff) | sel); radeon_emit(cs, new_fence); /* immediate data */ radeon_emit(cs, 0); /* unused */ if (buf) r600_emit_reloc(ctx, &ctx->gfx, buf, RADEON_USAGE_WRITE, RADEON_PRIO_QUERY); }
BOOL consoleDoWindow ( void ) /*++ Routine Description: Responds to a window event Arguments: None. Return Value: TRUE if window changed FALSE otherwise --*/ { PINPUT_RECORD pEvent; pEvent = NextEvent( NOADVANCE, NOWAIT ); if (( EVENT_TYPE(pEvent) ) == WINDOW_BUFFER_SIZE_EVENT) { pEvent = NextEvent( ADVANCE, WAIT ); WindowEvent(PWINDOW_EVT(pEvent)); } return FALSE; }
void r600_flush_emit(struct r600_context *rctx) { struct radeon_winsys_cs *cs = rctx->b.gfx.cs; unsigned cp_coher_cntl = 0; unsigned wait_until = 0; if (!rctx->b.flags) { return; } if (rctx->b.flags & R600_CONTEXT_WAIT_3D_IDLE) { wait_until |= S_008040_WAIT_3D_IDLE(1); } if (rctx->b.flags & R600_CONTEXT_WAIT_CP_DMA_IDLE) { wait_until |= S_008040_WAIT_CP_DMA_IDLE(1); } if (wait_until) { /* Use of WAIT_UNTIL is deprecated on Cayman+ */ if (rctx->b.family >= CHIP_CAYMAN) { /* emit a PS partial flush on Cayman/TN */ rctx->b.flags |= R600_CONTEXT_PS_PARTIAL_FLUSH; } } if (rctx->b.flags & R600_CONTEXT_PS_PARTIAL_FLUSH) { cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); } if (rctx->b.chip_class >= R700 && (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_CB_META)) { cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_FLUSH_AND_INV_CB_META) | EVENT_INDEX(0); } if (rctx->b.chip_class >= R700 && (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_DB_META)) { cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_FLUSH_AND_INV_DB_META) | EVENT_INDEX(0); /* Set FULL_CACHE_ENA for DB META flushes on r7xx and later. * * This hack predates use of FLUSH_AND_INV_DB_META, so it's * unclear whether it's still needed or even whether it has * any effect. */ cp_coher_cntl |= S_0085F0_FULL_CACHE_ENA(1); } if (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV || (rctx->b.chip_class == R600 && rctx->b.flags & R600_CONTEXT_STREAMOUT_FLUSH)) { cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); } if (rctx->b.flags & R600_CONTEXT_INV_CONST_CACHE) { /* Direct constant addressing uses the shader cache. * Indirect contant addressing uses the vertex cache. */ cp_coher_cntl |= S_0085F0_SH_ACTION_ENA(1) | (rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1) : S_0085F0_TC_ACTION_ENA(1)); } if (rctx->b.flags & R600_CONTEXT_INV_VERTEX_CACHE) { cp_coher_cntl |= rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1) : S_0085F0_TC_ACTION_ENA(1); } if (rctx->b.flags & R600_CONTEXT_INV_TEX_CACHE) { /* Textures use the texture cache. * Texture buffer objects use the vertex cache. */ cp_coher_cntl |= S_0085F0_TC_ACTION_ENA(1) | (rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1) : 0); } /* Don't use the DB CP COHER logic on r6xx. * There are hw bugs. */ if (rctx->b.chip_class >= R700 && (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_DB)) { cp_coher_cntl |= S_0085F0_DB_ACTION_ENA(1) | S_0085F0_DB_DEST_BASE_ENA(1) | S_0085F0_SMX_ACTION_ENA(1); } /* Don't use the CB CP COHER logic on r6xx. * There are hw bugs. */ if (rctx->b.chip_class >= R700 && (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_CB)) { cp_coher_cntl |= S_0085F0_CB_ACTION_ENA(1) | S_0085F0_CB0_DEST_BASE_ENA(1) | S_0085F0_CB1_DEST_BASE_ENA(1) | S_0085F0_CB2_DEST_BASE_ENA(1) | S_0085F0_CB3_DEST_BASE_ENA(1) | S_0085F0_CB4_DEST_BASE_ENA(1) | S_0085F0_CB5_DEST_BASE_ENA(1) | S_0085F0_CB6_DEST_BASE_ENA(1) | S_0085F0_CB7_DEST_BASE_ENA(1) | S_0085F0_SMX_ACTION_ENA(1); if (rctx->b.chip_class >= EVERGREEN) cp_coher_cntl |= S_0085F0_CB8_DEST_BASE_ENA(1) | S_0085F0_CB9_DEST_BASE_ENA(1) | S_0085F0_CB10_DEST_BASE_ENA(1) | S_0085F0_CB11_DEST_BASE_ENA(1); } if (rctx->b.chip_class >= R700 && rctx->b.flags & R600_CONTEXT_STREAMOUT_FLUSH) { cp_coher_cntl |= S_0085F0_SO0_DEST_BASE_ENA(1) | S_0085F0_SO1_DEST_BASE_ENA(1) | S_0085F0_SO2_DEST_BASE_ENA(1) | S_0085F0_SO3_DEST_BASE_ENA(1) | S_0085F0_SMX_ACTION_ENA(1); } /* Workaround for buggy flushing on some R6xx chipsets. */ if ((rctx->b.flags & (R600_CONTEXT_FLUSH_AND_INV | R600_CONTEXT_STREAMOUT_FLUSH)) && (rctx->b.family == CHIP_RV670 || rctx->b.family == CHIP_RS780 || rctx->b.family == CHIP_RS880)) { cp_coher_cntl |= S_0085F0_CB1_DEST_BASE_ENA(1) | S_0085F0_DEST_BASE_0_ENA(1); } if (cp_coher_cntl) { cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0); cs->buf[cs->cdw++] = cp_coher_cntl; /* CP_COHER_CNTL */ cs->buf[cs->cdw++] = 0xffffffff; /* CP_COHER_SIZE */ cs->buf[cs->cdw++] = 0; /* CP_COHER_BASE */ cs->buf[cs->cdw++] = 0x0000000A; /* POLL_INTERVAL */ } if (wait_until) { /* Use of WAIT_UNTIL is deprecated on Cayman+ */ if (rctx->b.family < CHIP_CAYMAN) { /* wait for things to settle */ radeon_set_config_reg(cs, R_008040_WAIT_UNTIL, wait_until); } } /* everything is properly flushed */ rctx->b.flags = 0; }
static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->cs; cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); }
/** * This function initializes all the compute specific registers that need to * be initialized for each compute command stream. Registers that are common * to both compute and 3D will be initialized at the beginning of each compute * command stream by the start_cs_cmd atom. However, since the SET_CONTEXT_REG * packet requires that the shader type bit be set, we must initialize all * context registers needed for compute in this function. The registers * intialized by the start_cs_cmd atom can be found in evereen_state.c in the * functions evergreen_init_atom_start_cs or cayman_init_atom_start_cs depending * on the GPU family. */ void evergreen_init_atom_start_compute_cs(struct r600_context *ctx) { struct r600_command_buffer *cb = &ctx->start_compute_cs_cmd; int num_threads; int num_stack_entries; /* since all required registers are initialised in the * start_compute_cs_cmd atom, we can EMIT_EARLY here. */ r600_init_command_buffer(cb, 256); cb->pkt_flags = RADEON_CP_PACKET3_COMPUTE_MODE; /* This must be first. */ r600_store_value(cb, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); r600_store_value(cb, 0x80000000); r600_store_value(cb, 0x80000000); /* We're setting config registers here. */ r600_store_value(cb, PKT3(PKT3_EVENT_WRITE, 0, 0)); r600_store_value(cb, EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4)); switch (ctx->family) { case CHIP_CEDAR: default: num_threads = 128; num_stack_entries = 256; break; case CHIP_REDWOOD: num_threads = 128; num_stack_entries = 256; break; case CHIP_JUNIPER: num_threads = 128; num_stack_entries = 512; break; case CHIP_CYPRESS: case CHIP_HEMLOCK: num_threads = 128; num_stack_entries = 512; break; case CHIP_PALM: num_threads = 128; num_stack_entries = 256; break; case CHIP_SUMO: num_threads = 128; num_stack_entries = 256; break; case CHIP_SUMO2: num_threads = 128; num_stack_entries = 512; break; case CHIP_BARTS: num_threads = 128; num_stack_entries = 512; break; case CHIP_TURKS: num_threads = 128; num_stack_entries = 256; break; case CHIP_CAICOS: num_threads = 128; num_stack_entries = 256; break; } /* Config Registers */ if (ctx->chip_class < CAYMAN) evergreen_init_common_regs(cb, ctx->chip_class, ctx->family, ctx->screen->info.drm_minor); else cayman_init_common_regs(cb, ctx->chip_class, ctx->family, ctx->screen->info.drm_minor); /* The primitive type always needs to be POINTLIST for compute. */ r600_store_config_reg(cb, R_008958_VGT_PRIMITIVE_TYPE, V_008958_DI_PT_POINTLIST); if (ctx->chip_class < CAYMAN) { /* These registers control which simds can be used by each stage. * The default for these registers is 0xffffffff, which means * all simds are available for each stage. It's possible we may * want to play around with these in the future, but for now * the default value is fine. * * R_008E20_SQ_STATIC_THREAD_MGMT1 * R_008E24_SQ_STATIC_THREAD_MGMT2 * R_008E28_SQ_STATIC_THREAD_MGMT3 */ /* XXX: We may need to adjust the thread and stack resouce * values for 3D/compute interop */ r600_store_config_reg_seq(cb, R_008C18_SQ_THREAD_RESOURCE_MGMT_1, 5); /* R_008C18_SQ_THREAD_RESOURCE_MGMT_1 * Set the number of threads used by the PS/VS/GS/ES stage to * 0. */ r600_store_value(cb, 0); /* R_008C1C_SQ_THREAD_RESOURCE_MGMT_2 * Set the number of threads used by the CS (aka LS) stage to * the maximum number of threads and set the number of threads * for the HS stage to 0. */ r600_store_value(cb, S_008C1C_NUM_LS_THREADS(num_threads)); /* R_008C20_SQ_STACK_RESOURCE_MGMT_1 * Set the Control Flow stack entries to 0 for PS/VS stages */ r600_store_value(cb, 0); /* R_008C24_SQ_STACK_RESOURCE_MGMT_2 * Set the Control Flow stack entries to 0 for GS/ES stages */ r600_store_value(cb, 0); /* R_008C28_SQ_STACK_RESOURCE_MGMT_3 * Set the Contol Flow stack entries to 0 for the HS stage, and * set it to the maximum value for the CS (aka LS) stage. */ r600_store_value(cb, S_008C28_NUM_LS_STACK_ENTRIES(num_stack_entries)); } /* Context Registers */ if (ctx->chip_class < CAYMAN) { /* workaround for hw issues with dyn gpr - must set all limits * to 240 instead of 0, 0x1e == 240 / 8 */ r600_store_context_reg(cb, R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1, S_028838_PS_GPRS(0x1e) | S_028838_VS_GPRS(0x1e) | S_028838_GS_GPRS(0x1e) | S_028838_ES_GPRS(0x1e) | S_028838_HS_GPRS(0x1e) | S_028838_LS_GPRS(0x1e)); } /* XXX: Investigate setting bit 15, which is FAST_COMPUTE_MODE */ r600_store_context_reg(cb, R_028A40_VGT_GS_MODE, S_028A40_COMPUTE_MODE(1) | S_028A40_PARTIAL_THD_AT_EOI(1)); r600_store_context_reg(cb, R_028B54_VGT_SHADER_STAGES_EN, 2/*CS_ON*/); r600_store_context_reg(cb, R_0286E8_SPI_COMPUTE_INPUT_CNTL, S_0286E8_TID_IN_GROUP_ENA | S_0286E8_TGID_ENA | S_0286E8_DISABLE_INDEX_PACK) ; /* The LOOP_CONST registers are an optimizations for loops that allows * you to store the initial counter, increment value, and maximum * counter value in a register so that hardware can calculate the * correct number of iterations for the loop, so that you don't need * to have the loop counter in your shader code. We don't currently use * this optimization, so we must keep track of the counter in the * shader and use a break instruction to exit loops. However, the * hardware will still uses this register to determine when to exit a * loop, so we need to initialize the counter to 0, set the increment * value to 1 and the maximum counter value to the 4095 (0xfff) which * is the maximum value allowed. This gives us a maximum of 4096 * iterations for our loops, but hopefully our break instruction will * execute before some time before the 4096th iteration. */ eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (160 * 4), 0x1000FFF); }
PINPUT_RECORD NextEvent ( BOOL fAdvance, BOOL fWait ) /*++ Routine Description: Returns pointer to next event record. Arguments: fAdvance - Supplies a flag: if TRUE: Advance to next event record if FALSE: Do not advance to next event record fWait - Supplies a flag: if TRUE, the blocks until an event is ready. if FALSE, return immediately. Return Value: Pointer to event record, or NULL. --*/ { PINPUT_RECORD pEvent; BOOL Success; EnterCriticalSection(&(EventBuffer.CriticalSection)); // // If the busy flag is set, then the buffer is in the process of // being read. Only one thread should want to wait, so it is // safe to simply return. // if ( EventBuffer.BusyFlag ) { assert( !fWait ); LeaveCriticalSection(&(EventBuffer.CriticalSection)); return NULL; } if (EventBuffer.NumberOfEvents == 0) { // // No events in buffer, read as many as we can // DWORD NumberOfEvents; // // If the buffer is too big, resize it // if ( EventBuffer.MaxEvents > MAX_EVENTS ) { EventBuffer.EventBuffer = REALLOC( EventBuffer.EventBuffer, MAX_EVENTS * sizeof( INPUT_RECORD ) ); EventBuffer.MaxEvents = MAX_EVENTS; assert( EventBuffer.EventBuffer ); if ( !EventBuffer.EventBuffer ) { CleanExit( 1, 0 ); } } Success = PeekConsoleInput( hInput, EventBuffer.EventBuffer, EventBuffer.MaxEvents, &NumberOfEvents); if ((!Success || (NumberOfEvents == 0)) && (!fWait)) { // // No events available and don't want to wait, // return. // LeaveCriticalSection(&(EventBuffer.CriticalSection)); return NULL; } // // Since we will block, we have to leave the critical section. // We set the Busy flag to indicate that the buffer is being // read. // EventBuffer.BusyFlag = TRUE; LeaveCriticalSection(&(EventBuffer.CriticalSection)); Success = ReadConsoleInput( hInput, EventBuffer.EventBuffer, NumberOfEvents, &EventBuffer.NumberOfEvents); EnterCriticalSection(&(EventBuffer.CriticalSection)); EventBuffer.BusyFlag = FALSE; if (!Success) { #if defined( DEBUG ) // OutputDebugString(" Error: Cannot read console events\n"); assert( Success ); #endif EventBuffer.NumberOfEvents = 0; } EventBuffer.EventIndex = 0; } if (EventBuffer.NumberOfEvents == 0) { #if defined( DEBUG ) // OutputDebugString(" Error: Cannot read console events\n"); assert( Success ); #endif return NULL; } pEvent = EventBuffer.EventBuffer + EventBuffer.EventIndex; // // If Advance flag is set, we advance the pointer to the next // record. // if (fAdvance) { if (--(EventBuffer.NumberOfEvents)) { switch (EVENT_TYPE(pEvent)) { case KEY_EVENT: case MOUSE_EVENT: case WINDOW_BUFFER_SIZE_EVENT: case MENU_EVENT: case FOCUS_EVENT: (EventBuffer.EventIndex)++; break; default: #if defined( DEBUG) sprintf(DbgBuffer, "WARNING: unknown event type %X\n", EVENT_TYPE(pEvent)); OutputDebugString(DbgBuffer); #endif (EventBuffer.EventIndex)++; break; } } } LeaveCriticalSection(&(EventBuffer.CriticalSection)); return pEvent; }
BOOL consoleGetKey ( PKBDKEY Key, BOOL fWait ) /*++ Routine Description: Gets the next key from the input buffer. Arguments: Key - Supplies a pointer to a key structure fWait - Supplies a flag: if TRUE, the function blocks until a key is ready. if FALSE, the function returns immediately. Return Value: TRUE if keystroke read, FALSE otherwise. --*/ { PINPUT_RECORD pEvent; do { pEvent = NextEvent( ADVANCE, fWait ); if (pEvent) { switch ( EVENT_TYPE(pEvent) ) { case KEY_EVENT: if (KeyEvent(PKEY_EVT(pEvent), Key)) { return TRUE; } break; case MOUSE_EVENT: MouseEvent(PMOUSE_EVT(pEvent)); break; case WINDOW_BUFFER_SIZE_EVENT: WindowEvent(PWINDOW_EVT(pEvent)); break; case MENU_EVENT: MenuEvent(PMENU_EVT(pEvent)); break; case FOCUS_EVENT: if (FocusEvent(PFOCUS_EVT(pEvent), Key)) { return TRUE; } break; default: break; } } } while (fWait); return FALSE; }
BOOL consolePeekKey ( PKBDKEY Key ) /*++ Routine Description: Gets the next key from the input buffer if the buffer is not empty. Arguments: Key - Supplies a pointer to a key structure Return Value: TRUE if keystroke read, FALSE otherwise. --*/ { PINPUT_RECORD pEvent; BOOL Done = FALSE; BOOL IsKey = FALSE; EnterCriticalSection(&(EventBuffer.PeekCriticalSection)); do { pEvent = NextEvent( NOADVANCE, NOWAIT ); if ( pEvent ) { switch ( EVENT_TYPE(pEvent) ) { case KEY_EVENT: if (KeyEvent(PKEY_EVT(pEvent), Key)){ IsKey = TRUE; Done = TRUE; } break; case MOUSE_EVENT: Done = TRUE; break; case WINDOW_BUFFER_SIZE_EVENT: Done = TRUE; break; case MENU_EVENT: case FOCUS_EVENT: Done = TRUE; break; default: assert( FALSE ); break; } if ( !Done ) { NextEvent( ADVANCE, NOWAIT ); } } else { Done = TRUE; } } while ( !Done ); LeaveCriticalSection(&(EventBuffer.PeekCriticalSection)); return IsKey; }
BOOL consoleIsKeyAvailable ( void ) /*++ Routine Description: Returns TRUE if a key is available in the event buffer. Arguments: None. Return Value: TRUE if a key is available in the event buffer FALSE otherwise --*/ { BOOL IsKey = FALSE; PINPUT_RECORD pEvent; DWORD Index; EnterCriticalSection( &(EventBuffer.CriticalSection) ); for (Index=EventBuffer.EventIndex; Index < EventBuffer.NumberOfEvents; Index++) { pEvent = EventBuffer.EventBuffer + Index; if ( ((EVENT_TYPE(pEvent)) == KEY_EVENT) && (PKEY_EVT(pEvent))->bKeyDown ) { IsKey = TRUE; break; } } LeaveCriticalSection( &(EventBuffer.CriticalSection) ); if (!IsKey) { EnterCriticalSection(&(EventBuffer.PeekCriticalSection)); pEvent = NextEvent( NOADVANCE, NOWAIT ); LeaveCriticalSection(&(EventBuffer.PeekCriticalSection)); EnterCriticalSection( &(EventBuffer.CriticalSection) ); if (pEvent != NULL) { for (Index=EventBuffer.EventIndex; Index < EventBuffer.NumberOfEvents; Index++) { pEvent = EventBuffer.EventBuffer + Index; if ( ((EVENT_TYPE(pEvent)) == KEY_EVENT) && (PKEY_EVT(pEvent))->bKeyDown ) { IsKey = TRUE; break; } } } LeaveCriticalSection( &(EventBuffer.CriticalSection) ); } return IsKey; }
static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout, const uint *grid_layout) { struct radeon_winsys_cs *cs = ctx->b.gfx.cs; unsigned i; /* make sure that the gfx ring is only one active */ if (ctx->b.dma.cs && ctx->b.dma.cs->cdw) { ctx->b.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL); } /* Initialize all the compute-related registers. * * See evergreen_init_atom_start_compute_cs() in this file for the list * of registers initialized by the start_compute_cs_cmd atom. */ r600_emit_command_buffer(cs, &ctx->start_compute_cs_cmd); /* emit config state */ if (ctx->b.chip_class == EVERGREEN) r600_emit_atom(ctx, &ctx->config_state.atom); ctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV; r600_flush_emit(ctx); /* Emit colorbuffers. */ /* XXX support more than 8 colorbuffers (the offsets are not a multiple of 0x3C for CB8-11) */ for (i = 0; i < 8 && i < ctx->framebuffer.state.nr_cbufs; i++) { struct r600_surface *cb = (struct r600_surface*)ctx->framebuffer.state.cbufs[i]; unsigned reloc = radeon_add_to_buffer_list(&ctx->b, &ctx->b.gfx, (struct r600_resource*)cb->base.texture, RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_RW_BUFFER); radeon_compute_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 7); radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */ radeon_emit(cs, cb->cb_color_pitch); /* R_028C64_CB_COLOR0_PITCH */ radeon_emit(cs, cb->cb_color_slice); /* R_028C68_CB_COLOR0_SLICE */ radeon_emit(cs, cb->cb_color_view); /* R_028C6C_CB_COLOR0_VIEW */ radeon_emit(cs, cb->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ radeon_emit(cs, cb->cb_color_attrib); /* R_028C74_CB_COLOR0_ATTRIB */ radeon_emit(cs, cb->cb_color_dim); /* R_028C78_CB_COLOR0_DIM */ radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C60_CB_COLOR0_BASE */ radeon_emit(cs, reloc); if (!ctx->keep_tiling_flags) { radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C70_CB_COLOR0_INFO */ radeon_emit(cs, reloc); } radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C74_CB_COLOR0_ATTRIB */ radeon_emit(cs, reloc); } if (ctx->keep_tiling_flags) { for (; i < 8 ; i++) { radeon_compute_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, S_028C70_FORMAT(V_028C70_COLOR_INVALID)); } for (; i < 12; i++) { radeon_compute_set_context_reg(cs, R_028E50_CB_COLOR8_INFO + (i - 8) * 0x1C, S_028C70_FORMAT(V_028C70_COLOR_INVALID)); } } /* Set CB_TARGET_MASK XXX: Use cb_misc_state */ radeon_compute_set_context_reg(cs, R_028238_CB_TARGET_MASK, ctx->compute_cb_target_mask); /* Emit vertex buffer state */ ctx->cs_vertex_buffer_state.atom.num_dw = 12 * util_bitcount(ctx->cs_vertex_buffer_state.dirty_mask); r600_emit_atom(ctx, &ctx->cs_vertex_buffer_state.atom); /* Emit constant buffer state */ r600_emit_atom(ctx, &ctx->constbuf_state[PIPE_SHADER_COMPUTE].atom); /* Emit sampler state */ r600_emit_atom(ctx, &ctx->samplers[PIPE_SHADER_COMPUTE].states.atom); /* Emit sampler view (texture resource) state */ r600_emit_atom(ctx, &ctx->samplers[PIPE_SHADER_COMPUTE].views.atom); /* Emit compute shader state */ r600_emit_atom(ctx, &ctx->cs_shader_state.atom); /* Emit dispatch state and dispatch packet */ evergreen_emit_direct_dispatch(ctx, block_layout, grid_layout); /* XXX evergreen_flush_emit() hardcodes the CP_COHER_SIZE to 0xffffffff */ ctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE | R600_CONTEXT_INV_VERTEX_CACHE | R600_CONTEXT_INV_TEX_CACHE; r600_flush_emit(ctx); ctx->b.flags = 0; if (ctx->b.chip_class >= CAYMAN) { cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4); /* DEALLOC_STATE prevents the GPU from hanging when a * SURFACE_SYNC packet is emitted some time after a DISPATCH_DIRECT * with any of the CB*_DEST_BASE_ENA or DB_DEST_BASE_ENA bits set. */ cs->buf[cs->cdw++] = PKT3C(PKT3_DEALLOC_STATE, 0, 0); cs->buf[cs->cdw++] = 0; } #if 0 COMPUTE_DBG(ctx->screen, "cdw: %i\n", cs->cdw); for (i = 0; i < cs->cdw; i++) { COMPUTE_DBG(ctx->screen, "%4i : 0x%08X\n", i, cs->buf[i]); } #endif }
void si_emit_cache_flush(struct radv_cmd_buffer *cmd_buffer) { enum chip_class chip_class = cmd_buffer->device->instance->physicalDevice.rad_info.chip_class; unsigned cp_coher_cntl = 0; radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 128); if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_INV_ICACHE) cp_coher_cntl |= S_0085F0_SH_ICACHE_ACTION_ENA(1); if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_INV_SMEM_L1) cp_coher_cntl |= S_0085F0_SH_KCACHE_ACTION_ENA(1); if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_INV_VMEM_L1) cp_coher_cntl |= S_0085F0_TCL1_ACTION_ENA(1); if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_INV_GLOBAL_L2) { cp_coher_cntl |= S_0085F0_TC_ACTION_ENA(1); if (chip_class >= VI) cp_coher_cntl |= S_0301F0_TC_WB_ACTION_ENA(1); } if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_FLUSH_AND_INV_CB) { cp_coher_cntl |= S_0085F0_CB_ACTION_ENA(1) | S_0085F0_CB0_DEST_BASE_ENA(1) | S_0085F0_CB1_DEST_BASE_ENA(1) | S_0085F0_CB2_DEST_BASE_ENA(1) | S_0085F0_CB3_DEST_BASE_ENA(1) | S_0085F0_CB4_DEST_BASE_ENA(1) | S_0085F0_CB5_DEST_BASE_ENA(1) | S_0085F0_CB6_DEST_BASE_ENA(1) | S_0085F0_CB7_DEST_BASE_ENA(1); /* Necessary for DCC */ if (cmd_buffer->device->instance->physicalDevice.rad_info.chip_class >= VI) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_FLUSH_AND_INV_CB_DATA_TS) | EVENT_INDEX(5)); radeon_emit(cmd_buffer->cs, 0); radeon_emit(cmd_buffer->cs, 0); radeon_emit(cmd_buffer->cs, 0); radeon_emit(cmd_buffer->cs, 0); } } if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_FLUSH_AND_INV_DB) { cp_coher_cntl |= S_0085F0_DB_ACTION_ENA(1) | S_0085F0_DB_DEST_BASE_ENA(1); } if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_FLUSH_AND_INV_CB_META) | EVENT_INDEX(0)); } if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_FLUSH_AND_INV_DB_META) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_FLUSH_AND_INV_DB_META) | EVENT_INDEX(0)); } if (!(cmd_buffer->state.flush_bits & (RADV_CMD_FLAG_FLUSH_AND_INV_CB | RADV_CMD_FLAG_FLUSH_AND_INV_DB))) { if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_PS_PARTIAL_FLUSH) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_PS_PARTIAL_FLUSH) | EVENT_INDEX(4)); } else if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_VS_PARTIAL_FLUSH) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_VS_PARTIAL_FLUSH) | EVENT_INDEX(4)); } } if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_CS_PARTIAL_FLUSH) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_CS_PARTIAL_FLUSH) | EVENT_INDEX(4)); } /* VGT state sync */ if (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_VGT_FLUSH) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0)); } /* Make sure ME is idle (it executes most packets) before continuing. * This prevents read-after-write hazards between PFP and ME. */ if (cp_coher_cntl || (cmd_buffer->state.flush_bits & RADV_CMD_FLAG_CS_PARTIAL_FLUSH)) { radeon_emit(cmd_buffer->cs, PKT3(PKT3_PFP_SYNC_ME, 0, 0)); radeon_emit(cmd_buffer->cs, 0); } /* When one of the DEST_BASE flags is set, SURFACE_SYNC waits for idle. * Therefore, it should be last. Done in PFP. */ if (cp_coher_cntl) { /* ACQUIRE_MEM is only required on a compute ring. */ radeon_emit(cmd_buffer->cs, PKT3(PKT3_SURFACE_SYNC, 3, 0)); radeon_emit(cmd_buffer->cs, cp_coher_cntl); /* CP_COHER_CNTL */ radeon_emit(cmd_buffer->cs, 0xffffffff); /* CP_COHER_SIZE */ radeon_emit(cmd_buffer->cs, 0); /* CP_COHER_BASE */ radeon_emit(cmd_buffer->cs, 0x0000000A); /* POLL_INTERVAL */ } cmd_buffer->state.flush_bits = 0; }