我对SDL_Texture的理解是:

  • 当您调用SDL_CreateTextureFromSurface()时,SDL_Texture位于主存储器上 .

  • 调用SDL_RenderCopy()时,纹理位于VRAM上 .

  • 当您调用SDL_DestroyTexture()时,纹理将从VRAM和主内存中释放 .

我对么?

我正在创建一个应用程序,在渲染它们之前一次创建大量纹理,因为图像非常大而且SDL_CreateTextureFromSurface()需要很长时间 . 当我一个接一个地使用SDL_RenderCopy()和SDL_RenderPresent()渲染它们时,VRAM的使用量一点一点地增加,并且在使用达到最大限制之后应用程序变慢 .

我想从VRAM中释放纹理,但不想从主内存中释放它,因为重新创建纹理需要很长时间 . 可能吗?

这是最小代码 . 它一直有效,直到专用GPU内存使用率达到100% . 在那之后,它变得非常缓慢 . (Windows10,Visual Studio 2017,NVIDIA P6000)

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <filesystem>
#include <thread>
#include <chrono>

#include "SDL.h"
#include "SDL_image.h"

int main(int argc, char** argv) {


    std::vector<SDL_Texture*> texture_list;
    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window* window = SDL_CreateWindow( "", 0, 0, 7680, 4320, SDL_WINDOW_BORDERLESS);

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    namespace fs = std::experimental::filesystem;

    for ( auto ent : fs::recursive_directory_iterator("c:\\picture\\1k") ) {
        if(!fs::is_directory(ent)){
            auto f = ent.path().generic_string();
            auto surface = IMG_Load(f.c_str());
            std::cout << "file:" << f << std::endl;
            auto tex = SDL_CreateTextureFromSurface(renderer, surface);
            if(!tex){
                std::cout << "SDL_CreateTextureFromSurface error" << std::endl;
                std::cout << SDL_GetError() << std::endl;
            }
            texture_list.push_back(tex);

            SDL_FreeSurface(surface);
        }
    }

    while (true) {
        for (auto tex : texture_list) {

            if(SDL_RenderClear(renderer) != 0){
                std::cout << "SDL_RenderClear error" << std::endl;
                std::cout << SDL_GetError() << std::endl;
            }
            if(SDL_RenderCopy(renderer, tex, NULL, NULL) < 0){
                std::cout << "SDL_RenderCopy error" << std::endl;
                std::cout << SDL_GetError() << std::endl;
            }
            SDL_RenderPresent(renderer);

            SDL_Delay(1);
            //std::cout << cnt++ << std::endl;
            SDL_Event event;

            if(SDL_PollEvent(&event)){
                std::cout << event.type << std::endl;
                switch (event.type) {
                    case SDL_KEYDOWN:
                        switch (event.key.keysym.sym) {
                            case SDLK_q:
                                exit(0);

                        }
                        break;
                }
            }
        }
    }

    return 0;
}