Пример #1
0
static void MemoryFill(const Regs::MemoryFillConfig& config) {
    const PAddr start_addr = config.GetStartAddress();
    const PAddr end_addr = config.GetEndAddress();

    // TODO: do hwtest with these cases
    if (!Memory::IsValidPhysicalAddress(start_addr)) {
        LOG_CRITICAL(HW_GPU, "invalid start address 0x%08X", start_addr);
        return;
    }

    if (!Memory::IsValidPhysicalAddress(end_addr)) {
        LOG_CRITICAL(HW_GPU, "invalid end address 0x%08X", end_addr);
        return;
    }

    if (end_addr <= start_addr) {
        LOG_CRITICAL(HW_GPU, "invalid memory range from 0x%08X to 0x%08X", start_addr, end_addr);
        return;
    }

    u8* start = Memory::GetPhysicalPointer(start_addr);
    u8* end = Memory::GetPhysicalPointer(end_addr);

    // TODO: Consider always accelerating and returning vector of
    //       regions that the accelerated fill did not cover to
    //       reduce/eliminate the fill that the cpu has to do.
    //       This would also mean that the flush below is not needed.
    //       Fill should first flush all surfaces that touch but are
    //       not completely within the fill range.
    //       Then fill all completely covered surfaces, and return the
    //       regions that were between surfaces or within the touching
    //       ones for cpu to manually fill here.
    if (VideoCore::g_renderer->Rasterizer()->AccelerateFill(config))
        return;

    Memory::RasterizerFlushAndInvalidateRegion(config.GetStartAddress(),
                                               config.GetEndAddress() - config.GetStartAddress());

    if (config.fill_24bit) {
        // fill with 24-bit values
        for (u8* ptr = start; ptr < end; ptr += 3) {
            ptr[0] = config.value_24bit_r;
            ptr[1] = config.value_24bit_g;
            ptr[2] = config.value_24bit_b;
        }
    } else if (config.fill_32bit) {
        // fill with 32-bit values
        if (end > start) {
            u32 value = config.value_32bit;
            size_t len = (end - start) / sizeof(u32);
            for (size_t i = 0; i < len; ++i)
                memcpy(&start[i * sizeof(u32)], &value, sizeof(u32));
        }
    } else {
        // fill with 16-bit values
        u16 value_16bit = config.value_16bit.Value();
        for (u8* ptr = start; ptr < end; ptr += sizeof(u16))
            memcpy(ptr, &value_16bit, sizeof(u16));
    }
}
Пример #2
0
static void MemoryFill(const Regs::MemoryFillConfig& config) {
    const PAddr start_addr = config.GetStartAddress();
    const PAddr end_addr = config.GetEndAddress();

    // TODO: do hwtest with these cases
    if (!Memory::IsValidPhysicalAddress(start_addr)) {
        LOG_CRITICAL(HW_GPU, "invalid start address {:#010X}", start_addr);
        return;
    }

    if (!Memory::IsValidPhysicalAddress(end_addr)) {
        LOG_CRITICAL(HW_GPU, "invalid end address {:#010X}", end_addr);
        return;
    }

    if (end_addr <= start_addr) {
        LOG_CRITICAL(HW_GPU, "invalid memory range from {:#010X} to {:#010X}", start_addr,
                     end_addr);
        return;
    }

    u8* start = Memory::GetPhysicalPointer(start_addr);
    u8* end = Memory::GetPhysicalPointer(end_addr);

    if (VideoCore::g_renderer->Rasterizer()->AccelerateFill(config))
        return;

    Memory::RasterizerInvalidateRegion(config.GetStartAddress(),
                                       config.GetEndAddress() - config.GetStartAddress());

    if (config.fill_24bit) {
        // fill with 24-bit values
        for (u8* ptr = start; ptr < end; ptr += 3) {
            ptr[0] = config.value_24bit_r;
            ptr[1] = config.value_24bit_g;
            ptr[2] = config.value_24bit_b;
        }
    } else if (config.fill_32bit) {
        // fill with 32-bit values
        if (end > start) {
            u32 value = config.value_32bit;
            size_t len = (end - start) / sizeof(u32);
            for (size_t i = 0; i < len; ++i)
                memcpy(&start[i * sizeof(u32)], &value, sizeof(u32));
        }
    } else {
        // fill with 16-bit values
        u16 value_16bit = config.value_16bit.Value();
        for (u8* ptr = start; ptr < end; ptr += sizeof(u16))
            memcpy(ptr, &value_16bit, sizeof(u16));
    }
}