Added SDL_GetTextureDXGIResource() to get the DXGI resource associated with a render texture.

Also switched the D3D11 and D3D12 renderers to use real NV12 textures for NV12 data.

The combination of these two changes allows us to implement 0-copy video decode and playback for D3D11 in testffmpeg without any access to the renderer internals.
This commit is contained in:
Sam Lantinga
2023-10-10 00:04:45 -07:00
parent a842446f62
commit 2bd478ae65
10 changed files with 336 additions and 265 deletions

View File

@@ -147,6 +147,7 @@ static Uint64 next_fps_check;
static Uint32 frames;
static const Uint32 fps_check_delay = 5000;
static Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
static SDL_Surface *MooseYUVSurfaces[MOOSEFRAMES_COUNT];
static SDL_Texture *MooseTexture = NULL;
static SDL_FRect displayrect;
@@ -187,31 +188,58 @@ static void MoveSprites(SDL_Renderer *renderer)
static int i = 0;
if (streaming) {
if (!paused) {
i = (i + 1) % MOOSEFRAMES_COUNT;
SDL_UpdateTexture(MooseTexture, NULL, MooseYUVSurfaces[i]->pixels, MooseYUVSurfaces[i]->pitch);
}
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, MooseTexture, NULL, &displayrect);
SDL_RenderPresent(renderer);
if (!paused) {
i = (i + 1) % MOOSEFRAMES_COUNT;
/* Test both upload paths for NV12/NV21 formats */
if ((yuv_format == SDL_PIXELFORMAT_NV12 || yuv_format == SDL_PIXELFORMAT_NV21) &&
(i % 2) == 0) {
#ifdef TEST_RECT_UPDATE
SDL_Rect rect;
if (i == 0) {
rect.x = 0;
rect.y = 0;
rect.w = MOOSEPIC_W;
rect.h = MOOSEPIC_H;
} else {
rect.x = MOOSEPIC_W / 4;
rect.y = MOOSEPIC_H / 4;
rect.w = MOOSEPIC_W / 2;
rect.h = MOOSEPIC_H / 2;
}
SDL_UpdateNVTexture(MooseTexture, &rect,
(Uint8 *)MooseYUVSurfaces[i]->pixels + rect.y * MooseYUVSurfaces[i]->pitch + rect.x, MooseYUVSurfaces[i]->pitch,
(Uint8 *)MooseYUVSurfaces[i]->pixels + MOOSEFRAME_SIZE + (rect.y + 1) / 2 * MooseYUVSurfaces[i]->pitch + (rect.x + 1) / 2, MooseYUVSurfaces[i]->pitch);
#else
SDL_UpdateNVTexture(MooseTexture, NULL,
MooseYUVSurfaces[i]->pixels, MooseYUVSurfaces[i]->pitch,
(Uint8 *)MooseYUVSurfaces[i]->pixels + MOOSEFRAME_SIZE, MooseYUVSurfaces[i]->pitch);
#endif
} else {
SDL_UpdateTexture(MooseTexture, NULL, MooseYUVSurfaces[i]->pixels, MooseYUVSurfaces[i]->pitch);
}
}
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, MooseTexture, NULL, &displayrect);
SDL_RenderPresent(renderer);
} else {
SDL_Texture *tmp;
SDL_Texture *tmp;
/* Test SDL_CreateTextureFromSurface */
if (!paused) {
i = (i + 1) % MOOSEFRAMES_COUNT;
}
/* Test SDL_CreateTextureFromSurface */
if (!paused) {
i = (i + 1) % MOOSEFRAMES_COUNT;
}
tmp = SDL_CreateTextureFromSurface(renderer, MooseYUVSurfaces[i]);
if (tmp == NULL) {
SDL_Log("Error %s", SDL_GetError());
quit(7);
}
tmp = SDL_CreateTextureFromSurface(renderer, MooseYUVSurfaces[i]);
if (tmp == NULL) {
SDL_Log("Error %s", SDL_GetError());
quit(7);
}
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, tmp, NULL, &displayrect);
SDL_RenderPresent(renderer);
SDL_DestroyTexture(tmp);
SDL_RenderClear(renderer);
SDL_RenderTexture(renderer, tmp, NULL, &displayrect);
SDL_RenderPresent(renderer);
SDL_DestroyTexture(tmp);
}
}
@@ -295,7 +323,6 @@ int main(int argc, char **argv)
int nodelay = 0;
int scale = 5;
char *filename = NULL;
int yuv_format = SDL_PIXELFORMAT_YV12;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);