first commit

This commit is contained in:
murdle
2026-03-01 02:38:58 +02:00
commit 19250b9db4
19111 changed files with 4358159 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
// gdraw_d3d.h - author: Sean Barrett - copyright 2009-2011 RAD Game Tools
//
// Interface for creating a D3D GDraw driver.
#include "gdraw.h"
#define IDOC
//idoc(parent,GDraw_d3d9)
typedef enum gdraw_d3d_resourcetype
{
GDRAW_D3D_RESOURCE_rendertarget,
GDRAW_D3D_RESOURCE_texture,
GDRAW_D3D_RESOURCE_vertexbuffer,
GDRAW_D3D_RESOURCE__count,
} gdraw_d3d_resourcetype;
IDOC extern int gdraw_D3D_SetResourceLimits(gdraw_d3d_resourcetype type, S32 num_handles, S32 num_bytes);
/* This sets how large the memory pool for a given resource types is, and how many handles
GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free
old resources in a LRU manner to make space if one of the limits is about to be exceeded.
Returns 1 if value successfully changed, 0 on error.
You need to call IggyPlayerFlushAll on all active Iggys before you do this to make
them flush their resources since changing the resource limits invalidates all handles.
You also need to call IggyFlushInstalledFonts if you have any installed fonts.
*/
IDOC extern GDrawFunctions * gdraw_D3D_CreateContext(IDirect3DDevice9 *dev, S32 w, S32 h);
/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device
and the width/height of the content you're displaying.
The width/height is used solely for sizing internal rendertargets. They will be
allocated to the larger of this size and the size of any rendered tiles (with padding).
In other words, you can pass in (0,0) and the rendertargets will be allocated to the
right size. However, if you draw multiple Iggy files or tiles of different sizes,
they might first be allocated too small; it's best to pass in the correct size initially
to avoid unnecessary allocation/deallocation of too-small rendertargets.
There can only be one D3D GDraw context active at any one time.
If initialization fails for some reason (the main reason would be an out of memory condition),
NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */
IDOC extern void gdraw_D3D_SetRendertargetSize(S32 w, S32 h);
/* Reset the size used for internal rendertargets defined by CreateContext. Flushes
all existing rendertargets if the size changes. */
IDOC extern void gdraw_D3D_DestroyContext(void);
/* Destroys the current GDraw context, if any. */
IDOC extern void gdraw_D3D_SetTileOrigin(IDirect3DSurface9 *rt, IDirect3DSurface9 *depth, S32 x, S32 y);
/* This sets the main rendertarget that GDraw should render to, the corresponding
depth/stencil surface, and the x/y position where to draw the top-left of the current tile (to be used for tiled
rendering). You need to call this before Iggy calls any rendering functions. */
IDOC extern void gdraw_D3D_NoMoreGDrawThisFrame(void);
/* Tells GDraw that no more rendering operations will occur this frame. This triggers
some end-of-frame processing; most importantly, GDraw uses this call as a marker to
detect thrashing (and react accordingly), so please do not forget to call this
every frame! (As long as Iggy does any rendering, that is) */
IDOC extern void gdraw_D3D_PreReset(void);
/* Call this before D3D device Reset(); it will free all default pool resources allocated
by GDraw. */
IDOC extern void gdraw_D3D_PostReset(void);
/* Call after D3D device Reset(). */
IDOC extern void RADLINK gdraw_D3D_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, D3DMATRIX *mat);
/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has
set on the D3D device, and to get the current 2D object-to-world transformation. */
IDOC extern void RADLINK gdraw_D3D_EndCustomDraw(IggyCustomDrawCallbackRegion *Region);
/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */
IDOC extern void RADLINK gdraw_D3D_GetResourceUsageStats(gdraw_d3d_resourcetype type, S32 *handles_used, S32 *bytes_used);
/* D3D only: Get resource usage stats for last frame.
This can be used to get an estimate of how much graphics memory got used by GDraw
during the last frame.
Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually
has its own management overhead, alignment requirements, allocation granularity
and so on. In short, this is not an accurate estimate of how much memory is actually
used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */
IDOC extern GDrawTexture *gdraw_D3D_WrappedTextureCreate(IDirect3DTexture9 *tex_handle);
/* Create a wrapped texture from a D3D texture.
A wrapped texture can be used to let Iggy draw using the contents of a texture
you create and manage on your own. For example, you might render to this texture,
or stream video into it. Wrapped textures take up a handle. They will never be
freed or otherwise modified by GDraw; nor will GDraw change any reference counts.
All this is up to the application. */
IDOC extern void gdraw_D3D_WrappedTextureChange(GDrawTexture *tex, IDirect3DTexture9 *tex_handle);
/* Switch an existing GDrawTexture * that represents a wrapped texture to use
a new underlying D3D texture. For example, you might internally double-buffer
a dynamically updated texture. As above, GDraw will leave this texture alone
and not touch any reference counts. */
IDOC extern void gdraw_D3D_WrappedTextureDestroy(GDrawTexture *tex);
/* Destroys the GDraw wrapper for a wrapped texture object. This will free up
a GDraw texture handle but not release the associated D3D texture; that is
up to you. */
extern GDrawTexture * RADLINK gdraw_D3D_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture);
extern void RADLINK gdraw_D3D_DestroyTextureFromResource(GDrawTexture *tex);

View File

@@ -0,0 +1,138 @@
// gdraw_d3d10.cpp - author: Fabian Giesen - copyright 2011 RAD Game Tools
//
// This implements the Iggy graphics driver layer for D3D 10.
// GDraw consists of several components that interact fairly loosely with each other;
// e.g. the resource management, drawing and filtering parts are all fairly independent
// of each other. If you want to modify some aspect of GDraw - say the texture allocation
// logic - your best bet is usually to just look for one of the related entry points,
// e.g. MakeTextureBegin, and take it from there. There's a bunch of code in this file,
// but none of it is really complicated.
//
// The one bit you might want to change that's not that localized is to integrate
// GDraw with an existing state caching system. The following bits all modify D3D state
// in some way:
// - The rendering helpers (set_viewport_raw, set_projection_raw, set_*_renderstate)
// - RenderTile*/TextureDrawBuffer* may change the active rendertarget and depth/stencil surface,
// as do D3D1X_(NoMoreGDrawThisFrame) and set_render_target
// - set_texture
// - set_renderstate and set_renderstate_full. These are the main places where render state changes occur;
// you should probably start here.
// - DrawIndexedTriangles sets the active vertex/index buffers and vertex declaration
// - Most of the functions in the "filter effects" section modify D3D state, mostly
// pixel shader constants and textures
#define GDRAW_ASSERTS
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// We temporarily disable this warning for the shared interface portions
#pragma warning (push)
#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union
#include <windows.h>
#include <d3d10.h>
#include "gdraw.h"
#include "iggy.h"
#include <string.h>
#include <math.h>
#include "gdraw_d3d10.h"
#pragma warning (pop)
// Some macros to allow as much sharing between D3D10 and D3D11 code as possible.
#define D3D1X_(id) D3D10_##id
#define ID3D1X(id) ID3D10##id
#define gdraw_D3D1X_(id) gdraw_D3D10_##id
#define GDRAW_D3D1X_(id) GDRAW_D3D10_##id
typedef ID3D10Device ID3D1XDevice;
typedef ID3D10Device ID3D1XContext;
typedef S32 ViewCoord;
typedef gdraw_d3d10_resourcetype gdraw_resourcetype;
static void report_d3d_error(HRESULT hr, char *call, char *context);
static void *map_buffer(ID3D1XContext *, ID3D10Buffer *buf, bool discard)
{
void *ptr;
if (FAILED(buf->Map(discard ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE, 0, &ptr)))
return NULL;
else
return ptr;
}
static void unmap_buffer(ID3D1XContext *, ID3D10Buffer *buf)
{
buf->Unmap();
}
static RADINLINE void set_pixel_shader(ID3D10Device *ctx, ID3D10PixelShader *shader)
{
ctx->PSSetShader(shader);
}
static RADINLINE void set_vertex_shader(ID3D10Device *ctx, ID3D10VertexShader *shader)
{
ctx->VSSetShader(shader);
}
static ID3D10BlendState *create_blend_state(ID3D10Device *dev, BOOL blend, D3D10_BLEND src, D3D10_BLEND dst)
{
D3D10_BLEND_DESC desc = {};
desc.BlendEnable[0] = blend;
desc.SrcBlend = src;
desc.DestBlend = dst;
desc.BlendOp = D3D10_BLEND_OP_ADD;
desc.SrcBlendAlpha = (src == D3D10_BLEND_DEST_COLOR ) ? D3D10_BLEND_DEST_ALPHA : src;
desc.DestBlendAlpha = dst;
desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
ID3D10BlendState *res;
HRESULT hr = dev->CreateBlendState(&desc, &res);
if (FAILED(hr)) {
report_d3d_error(hr, "CreateBlendState", "");
res = NULL;
}
return res;
}
#define GDRAW_SHADER_FILE "gdraw_d3d10_shaders.inl"
#include "gdraw_d3d1x_shared.inl"
static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src)
{
*p = *src;
if(p->bytecode) {
HRESULT hr = gdraw->d3d_device->CreatePixelShader(p->bytecode, p->size, &p->pshader);
if (FAILED(hr)) {
report_d3d_error(hr, "CreatePixelShader", "");
p->pshader = NULL;
return;
}
}
}
static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src)
{
*p = *src;
if(p->bytecode) {
HRESULT hr = gdraw->d3d_device->CreateVertexShader(p->bytecode, p->size, &p->vshader);
if (FAILED(hr)) {
report_d3d_error(hr, "CreateVertexShader", "");
p->vshader = NULL;
return;
}
}
}
GDrawFunctions *gdraw_D3D10_CreateContext(ID3D10Device *dev, S32 w, S32 h)
{
return create_context(dev, dev, w, h);
}

View File

@@ -0,0 +1,132 @@
// gdraw_d3d10.h - author: Fabian Giesen - copyright 2011 RAD Game Tools
//
// Interface for creating a D3D10 GDraw driver.
#define IDOC
//idoc(parent,GDraw_d3d10)
typedef enum gdraw_d3d10_resourcetype
{
GDRAW_D3D10_RESOURCE_rendertarget,
GDRAW_D3D10_RESOURCE_texture,
GDRAW_D3D10_RESOURCE_vertexbuffer,
GDRAW_D3D10_RESOURCE_dynbuffer, // Streaming buffer for dynamic vertex/index data (handle count ignored)
GDRAW_D3D10_RESOURCE__count,
} gdraw_d3d10_resourcetype;
IDOC extern int gdraw_D3D10_SetResourceLimits(gdraw_d3d10_resourcetype type, S32 num_handles, S32 num_bytes);
/* This sets how large the memory pool for a given resource types is, and how many handles
GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free
old resources in a LRU manner to make space if one of the limits is about to be exceeded.
Returns 1 if value successfully changed, 0 on error.
You need to call IggyPlayerFlushAll on all active Iggys before you do this to make
them flush their resources since changing the resource limits invalidates all handles.
You also need to call IggyFlushInstalledFonts if you have any installed fonts.
*/
IDOC extern GDrawFunctions * gdraw_D3D10_CreateContext(ID3D10Device *dev, S32 w, S32 h);
/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device
and the width/height of render target textures.
The width/height is used solely for sizing internal rendertargets. They will be
allocated to the larger of this size and the size of any rendered tiles (with padding).
In other words, you can pass in (0,0) and the rendertargets will be allocated to the
right size. However, if you draw multiple Iggy files or tiles of different sizes,
they might first be allocated too small; it's best to pass in the correct size initially
to avoid unnecessary allocation/deallocation of too-small rendertargets.
There can only be one D3D GDraw context active at any one time.
If initialization fails for some reason (the main reason would be an out of memory condition),
NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */
IDOC extern void gdraw_D3D10_DestroyContext(void);
/* Destroys the current GDraw context, if any. */
IDOC extern void gdraw_D3D10_SetErrorHandler(void (__cdecl *error_handler)(HRESULT hr));
/* Sets the GDraw D3D error handler.
This will get called with the respective D3D error code if GDraw encounters an error
that it can't handle by itself (e.g. running out of state objects). */
IDOC extern void gdraw_D3D10_SetRendertargetSize(S32 w, S32 h);
/* Changes the current render target size (and recreates all rendertargets if necessary).
This allows you to shrink the rendertargets if the new needed size is smaller
than it was previously. As with $gdraw_D3D10_CreateContext, the width and
height specified here are only minimums; GDraw will reallocate larger rendertargets
as needed. */
IDOC extern void gdraw_D3D10_SetTileOrigin(ID3D10RenderTargetView *main_rt, ID3D10DepthStencilView *main_ds,
ID3D10ShaderResourceView *non_msaa_rt, S32 x, S32 y);
/* This sets the main rendertarget and matching depth/stencil buffer that GDraw
should render to and the x/y position of the output location of the top-left
of the current tile (allowing you to finely-position content, or to do tiled
rendering).
If your rendertarget uses multisampling, you also need to specify a shader
resource view for a non-MSAA rendertarget texture (identically sized to main_rt)
in non_msaa_rt. This is only used if the Flash content includes non-standard
blend modes which have to use a special blend shader, so you can leave it NULL
if you forbid such content.
You need to call this before Iggy calls any rendering functions. */
IDOC extern void gdraw_D3D10_NoMoreGDrawThisFrame(void);
/* Tells GDraw that no more rendering operations will occur this frame. This triggers
some end-of-frame processing; most importantly, GDraw uses this call as a marker to
detect thrashing (and react accordingly), so please do not forget to call this
every frame! (As long as Iggy does any rendering, that is) */
IDOC extern void gdraw_D3D10_PreReset(void);
/* Call this before D3D device Reset(); it will free all default pool resources allocated
by GDraw. */
IDOC extern void gdraw_D3D10_PostReset(void);
/* Call after D3D device Reset(). */
IDOC extern void RADLINK gdraw_D3D10_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, F32 mat[4][4]);
/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has
set on the D3D device, and to get the current 2D object-to-world transformation. */
IDOC extern void RADLINK gdraw_D3D10_EndCustomDraw(IggyCustomDrawCallbackRegion *Region);
/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */
IDOC extern void RADLINK gdraw_D3D10_GetResourceUsageStats(gdraw_d3d10_resourcetype type, S32 *handles_used, S32 *bytes_used);
/* D3D only: Get resource usage stats for last frame.
This can be used to get an estimate of how much graphics memory got used by GDraw
during the last frame.
For the dynbuffer, this always returns 0 in handles_used and the *size of the largest
single allocation* in bytes_used. It needs to be sized so that this allocation fits;
make it smaller and it won't work, but if you make it much larger (say more than 2x
as big), it's just a waste of memory. That said, we still recommend to make it no
smaller than 64k, and the default is 256k.
Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually
has its own management overhead, alignment requirements, allocation granularity
and so on. In short, this is not an accurate estimate of how much memory is actually
used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */
IDOC extern GDrawTexture *gdraw_D3D10_WrappedTextureCreate(ID3D10ShaderResourceView *tex_view);
/* Create a wrapped texture from a shader resource view.
A wrapped texture can be used to let Iggy draw using the contents of a texture
you create and manage on your own. For example, you might render to this texture,
or stream video into it. Wrapped textures take up a handle. They will never be
freed or otherwise modified by GDraw; nor will GDraw change any reference counts.
All this is up to the application. */
IDOC extern void gdraw_D3D10_WrappedTextureChange(GDrawTexture *tex, ID3D10ShaderResourceView *tex_view);
/* Switch an existing GDrawTexture * that represents a wrapped texture to use
a new underlying D3D view. For example, you might internally double-buffer
a dynamically updated texture. As above, GDraw will leave this texture alone
and not touch any reference counts. */
IDOC extern void gdraw_D3D10_WrappedTextureDestroy(GDrawTexture *tex);
/* Destroys the GDraw wrapper for a wrapped texture object. This will free up
a GDraw texture handle but not release the associated D3D texture; that is
up to you. */
extern GDrawTexture * RADLINK gdraw_D3D10_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture);
extern void RADLINK gdraw_D3D10_DestroyTextureFromResource(GDrawTexture *tex);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
#include "stdafx.h" // 4J
// gdraw_d3d11.cpp - author: Fabian Giesen - copyright 2011 RAD Game Tools
//
// This implements the Iggy graphics driver layer for D3D 11.
// GDraw consists of several components that interact fairly loosely with each other;
// e.g. the resource management, drawing and filtering parts are all fairly independent
// of each other. If you want to modify some aspect of GDraw - say the texture allocation
// logic - your best bet is usually to just look for one of the related entry points,
// e.g. MakeTextureBegin, and take it from there. There's a bunch of code in this file,
// but none of it is really complicated.
//
// The one bit you might want to change that's not that localized is to integrate
// GDraw with an existing state caching system. The following bits all modify D3D state
// in some way:
// - The rendering helpers (set_viewport_raw, set_projection_raw, set_*_renderstate)
// - RenderTile*/TextureDrawBuffer* may change the active rendertarget and depth/stencil surface,
// as do D3D1X_(NoMoreGDrawThisFrame) and set_render_target
// - set_texture
// - set_renderstate and set_renderstate_full. These are the main places where render state changes occur;
// you should probably start here.
// - DrawIndexedTriangles sets the active vertex/index buffers and vertex declaration
// - Most of the functions in the "filter effects" section modify D3D state, mostly
// pixel shader constants and textures
#define GDRAW_ASSERTS
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// We temporarily disable this warning for the shared interface portions
#pragma warning (push)
#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union
#include <windows.h>
#include <d3d11.h>
#include "gdraw.h"
#include "iggy.h"
#include <string.h>
#include <math.h>
#include "gdraw_d3d11.h"
#pragma warning (pop)
// Some macros to allow as much sharing between D3D10 and D3D11 code as possible.
#define D3D1X_(id) D3D11_##id
#define ID3D1X(id) ID3D11##id
#define gdraw_D3D1X_(id) gdraw_D3D11_##id
#define GDRAW_D3D1X_(id) GDRAW_D3D11_##id
typedef ID3D11Device ID3D1XDevice;
typedef ID3D11DeviceContext ID3D1XContext;
typedef F32 ViewCoord;
typedef gdraw_d3d11_resourcetype gdraw_resourcetype;
static void report_d3d_error(HRESULT hr, char *call, char *context);
static void *map_buffer(ID3D1XContext *ctx, ID3D11Buffer *buf, bool discard)
{
D3D11_MAPPED_SUBRESOURCE msr;
HRESULT hr = ctx->Map(buf, 0, discard ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &msr);
if (FAILED(hr)) {
report_d3d_error(hr, "Map", "of buffer");
return NULL;
} else
return msr.pData;
}
static void unmap_buffer(ID3D1XContext *ctx, ID3D11Buffer *buf)
{
ctx->Unmap(buf, 0);
}
static RADINLINE void set_pixel_shader(ID3D11DeviceContext *ctx, ID3D11PixelShader *shader)
{
ctx->PSSetShader(shader, NULL, 0);
}
static RADINLINE void set_vertex_shader(ID3D11DeviceContext *ctx, ID3D11VertexShader *shader)
{
ctx->VSSetShader(shader, NULL, 0);
}
static ID3D11BlendState *create_blend_state(ID3D11Device *dev, BOOL blend, D3D11_BLEND src, D3D11_BLEND dst)
{
D3D11_BLEND_DESC desc = {};
desc.RenderTarget[0].BlendEnable = blend;
desc.RenderTarget[0].SrcBlend = src;
desc.RenderTarget[0].DestBlend = dst;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = (src == D3D11_BLEND_DEST_COLOR ) ? D3D11_BLEND_DEST_ALPHA : src;
desc.RenderTarget[0].DestBlendAlpha = dst;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
ID3D11BlendState *res;
HRESULT hr = dev->CreateBlendState(&desc, &res);
if (FAILED(hr)) {
report_d3d_error(hr, "CreateBlendState", "");
res = NULL;
}
return res;
}
#define GDRAW_SHADER_FILE "gdraw_d3d10_shaders.inl"
#include "gdraw_d3d1x_shared.inl"
static void create_pixel_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src)
{
*p = *src;
if(p->bytecode) {
HRESULT hr = gdraw->d3d_device->CreatePixelShader(p->bytecode, p->size, NULL, &p->pshader);
if (FAILED(hr)) {
report_d3d_error(hr, "CreatePixelShader", "");
p->pshader = NULL;
return;
}
}
}
static void create_vertex_shader(ProgramWithCachedVariableLocations *p, ProgramWithCachedVariableLocations *src)
{
*p = *src;
if(p->bytecode) {
HRESULT hr = gdraw->d3d_device->CreateVertexShader(p->bytecode, p->size, NULL, &p->vshader);
if (FAILED(hr)) {
report_d3d_error(hr, "CreateVertexShader", "");
p->vshader = NULL;
return;
}
}
}
GDrawFunctions *gdraw_D3D11_CreateContext(ID3D11Device *dev, ID3D11DeviceContext *ctx, S32 w, S32 h)
{
return create_context(dev, ctx, w, h);
}
// 4J added - interface so we can set the viewport back to the one that Iggy last set up
void gdraw_D3D11_setViewport_4J()
{
set_viewport();
}

View File

@@ -0,0 +1,139 @@
#pragma once // 4J
// gdraw_d3d11.h - author: Fabian Giesen - copyright 2011 RAD Game Tools
//
// Interface for creating a D3D11 GDraw driver.
#define IDOC
//idoc(parent,GDraw_d3d11)
typedef enum gdraw_d3d11_resourcetype
{
GDRAW_D3D11_RESOURCE_rendertarget,
GDRAW_D3D11_RESOURCE_texture,
GDRAW_D3D11_RESOURCE_vertexbuffer,
GDRAW_D3D11_RESOURCE_dynbuffer, // Streaming buffer for dynamic vertex/index data (handle count ignored)
GDRAW_D3D11_RESOURCE__count,
} gdraw_d3d11_resourcetype;
IDOC extern int gdraw_D3D11_SetResourceLimits(gdraw_d3d11_resourcetype type, S32 num_handles, S32 num_bytes);
/* This sets how large the memory pool for a given resource types is, and how many handles
GDraw should allocate for it. GDraw keeps track of allocations in each pool, and will free
old resources in a LRU manner to make space if one of the limits is about to be exceeded.
Returns 1 if value successfully changed, 0 on error.
You need to call IggyPlayerFlushAll on all active Iggys before you do this to make
them flush their resources since changing the resource limits invalidates all handles.
You also need to call IggyFlushInstalledFonts if you have any installed fonts.
*/
IDOC extern GDrawFunctions * gdraw_D3D11_CreateContext(ID3D11Device *dev, ID3D11DeviceContext *ctx, S32 w, S32 h);
/* Creates a GDraw context for rendering using D3D. You need to pass in the D3D device,
the device context to use for rendering, and the width/height of render target textures.
The width/height is used solely for sizing internal rendertargets. They will be
allocated to the larger of this size and the size of any rendered tiles (with padding).
In other words, you can pass in (0,0) and the rendertargets will be allocated to the
right size. However, if you draw multiple Iggy files or tiles of different sizes,
they might first be allocated too small; it's best to pass in the correct size initially
to avoid unnecessary allocation/deallocation of too-small rendertargets.
There can only be one D3D GDraw context active at any one time.
If initialization fails for some reason (the main reason would be an out of memory condition),
NULL is returned. Otherwise, you can pass the return value to IggySetGDraw. */
IDOC extern void gdraw_D3D11_DestroyContext(void);
/* Destroys the current GDraw context, if any. */
IDOC extern void gdraw_D3D11_SetErrorHandler(void (__cdecl *error_handler)(HRESULT hr));
/* Sets the GDraw D3D error handler.
This will get called with the respective D3D error code if GDraw encounters an error
that it can't handle by itself (e.g. running out of state objects). */
IDOC extern void gdraw_D3D11_SetRendertargetSize(S32 w, S32 h);
/* Changes the current render target size (and recreates all rendertargets if necessary).
This allows you to shrink the rendertargets if the new needed size is smaller
than it was previously. As with $gdraw_D3D11_CreateContext, the width and
height specified here are only minimums; GDraw will reallocate larger rendertargets
as needed. */
IDOC extern void gdraw_D3D11_SetTileOrigin(ID3D11RenderTargetView *main_rt, ID3D11DepthStencilView *main_ds,
ID3D11ShaderResourceView *non_msaa_rt, S32 x, S32 y);
/* This sets the main rendertarget and matching depth/stencil buffer that GDraw
should render to and the x/y position of the output location of the top-left
of the current tile (allowing you to finely-position content, or to do tiled
rendering).
If your rendertarget uses multisampling, you also need to specify a shader
resource view for a non-MSAA rendertarget texture (identically sized to main_rt)
in non_msaa_rt. This is only used if the Flash content includes non-standard
blend modes which have to use a special blend shader, so you can leave it NULL
if you forbid such content.
You need to call this before Iggy calls any rendering functions. */
IDOC extern void gdraw_D3D11_NoMoreGDrawThisFrame(void);
/* Tells GDraw that no more rendering operations will occur this frame. This triggers
some end-of-frame processing; most importantly, GDraw uses this call as a marker to
detect thrashing (and react accordingly), so please do not forget to call this
every frame! (As long as Iggy does any rendering, that is) */
IDOC extern void gdraw_D3D11_PreReset(void);
/* Call this before D3D device Reset(); it will free all default pool resources allocated
by GDraw. */
IDOC extern void gdraw_D3D11_PostReset(void);
/* Call after D3D device Reset(). */
IDOC extern void RADLINK gdraw_D3D11_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion *Region, F32 mat[16]);
IDOC extern void RADLINK gdraw_D3D11_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion *Region, F32 mat[16]);
IDOC extern void RADLINK gdraw_D3D11_BeginCustomDraw(IggyCustomDrawCallbackRegion *Region, F32 mat[4][4]);
/* Call at the beginning of Iggy custom draw callback to clear any odd render states GDraw has
set on the D3D device, and to get the current 2D object-to-world transformation. */
IDOC extern void RADLINK gdraw_D3D11_EndCustomDraw(IggyCustomDrawCallbackRegion *Region);
/* Call at the end of Iggy custom draw callback so GDraw can restore its render states. */
IDOC extern void RADLINK gdraw_D3D11_GetResourceUsageStats(gdraw_d3d11_resourcetype type, S32 *handles_used, S32 *bytes_used);
/* D3D only: Get resource usage stats for last frame.
This can be used to get an estimate of how much graphics memory got used by GDraw
during the last frame.
For the dynbuffer, this always returns 0 in handles_used and the *size of the largest
single allocation* in bytes_used. It needs to be sized so that this allocation fits;
make it smaller and it won't work, but if you make it much larger (say more than 2x
as big), it's just a waste of memory. That said, we still recommend to make it no
smaller than 64k, and the default is 256k.
Caveat: This counts the number of bytes that GDraw knows about. 3D hardware usually
has its own management overhead, alignment requirements, allocation granularity
and so on. In short, this is not an accurate estimate of how much memory is actually
used by the GPU - it is a lower bound, though, and makes for a useful ballpark estimate. */
IDOC extern GDrawTexture *gdraw_D3D11_WrappedTextureCreate(ID3D11ShaderResourceView *tex_view);
/* Create a wrapped texture from a shader resource view.
A wrapped texture can be used to let Iggy draw using the contents of a texture
you create and manage on your own. For example, you might render to this texture,
or stream video into it. Wrapped textures take up a handle. They will never be
freed or otherwise modified by GDraw; nor will GDraw change any reference counts.
All this is up to the application. */
IDOC extern void gdraw_D3D11_WrappedTextureChange(GDrawTexture *tex, ID3D11ShaderResourceView *tex_view);
/* Switch an existing GDrawTexture * that represents a wrapped texture to use
a new underlying D3D view. For example, you might internally double-buffer
a dynamically updated texture. As above, GDraw will leave this texture alone
and not touch any reference counts. */
IDOC extern void gdraw_D3D11_WrappedTextureDestroy(GDrawTexture *tex);
/* Destroys the GDraw wrapper for a wrapped texture object. This will free up
a GDraw texture handle but not release the associated D3D texture; that is
up to you. */
GDrawTexture * RADLINK gdraw_D3D11_MakeTextureFromResource(U8 *resource_file, S32 length, IggyFileTextureRaw *texture);
void RADLINK gdraw_D3D11_DestroyTextureFromResource(GDrawTexture *tex);
// 4J added
extern void RADLINK gdraw_D3D11_setViewport_4J();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
// gdraw_wgl.c - copyright 2011-2012 RAD Game Tools
//
// This implements the Iggy graphics driver layer for GL on Windows.
#define GDRAW_ASSERTS
#include "iggy.h"
#include "gdraw.h"
#include "gdraw_wgl.h"
#include <windows.h>
#include <gl/gl.h>
#include "glext.h"
#include <string.h>
#include <math.h>
#define true 1
#define false 0
///////////////////////////////////////////////////////////////////////////////
//
// Extensions (we map to GL 2.0 function names for a uniform interface
// across platforms)
//
#define GDRAW_GL_EXTENSION_LIST \
/* identifier import procname */ \
/* GL_ARB_multitexture */ \
GLE(ActiveTexture, "ActiveTextureARB", ACTIVETEXTUREARB) \
/* GL_ARB_texture_compression */ \
GLE(CompressedTexImage2D, "CompressedTexImage2DARB", COMPRESSEDTEXIMAGE2DARB) \
/* GL_ARB_vertex_buffer_object */ \
GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \
GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \
GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \
GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \
GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \
GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \
GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \
GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", ENABLEVERTEXATTRIBARRAYARB) \
GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", DISABLEVERTEXATTRIBARRAYARB) \
/* GL_ARB_shader_objects */ \
GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \
GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \
GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \
GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \
GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \
GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \
GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \
GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \
GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \
GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \
GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \
GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \
GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \
/* GL_ARB_vertex_shader */ \
GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \
/* GL_EXT_framebuffer_object */ \
GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \
GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \
GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \
GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \
GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \
GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \
GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \
GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", CHECKFRAMEBUFFERSTATUSEXT) \
GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", FRAMEBUFFERRENDERBUFFEREXT) \
GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", FRAMEBUFFERTEXTURE2DEXT) \
GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \
/* GL_EXT_framebuffer_blit */ \
GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \
/* GL_EXT_framebuffer_multisample */ \
GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT",RENDERBUFFERSTORAGEMULTISAMPLEEXT) \
/* <end> */
#define gdraw_GLx_(id) gdraw_GL_##id
#define GDRAW_GLx_(id) GDRAW_GL_##id
#define GDRAW_SHADERS "gdraw_gl_shaders.inl"
typedef GLhandleARB GLhandle;
typedef gdraw_gl_resourcetype gdraw_resourcetype;
// Extensions
#define GLE(id, import, procname) static PFNGL##procname##PROC gl##id;
GDRAW_GL_EXTENSION_LIST
#undef GLE
static void load_extensions(void)
{
#define GLE(id, import, procname) gl##id = (PFNGL##procname##PROC) wglGetProcAddress("gl" import);
GDRAW_GL_EXTENSION_LIST
#undef GLE
}
static void clear_renderstate_platform_specific(void)
{
glDisable(GL_ALPHA_TEST);
}
static void error_msg_platform_specific(const char *msg)
{
OutputDebugStringA(msg);
}
///////////////////////////////////////////////////////////////////////////////
//
// Shared code
//
#define GDRAW_MULTISAMPLING
#include "gdraw_gl_shared.inl"
///////////////////////////////////////////////////////////////////////////////
//
// Initialization and platform-specific functionality
//
GDrawFunctions *gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples)
{
static const TextureFormatDesc tex_formats[] = {
{ IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 },
{ IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 },
{ IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_UNSIGNED_BYTE },
{ IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_UNSIGNED_BYTE },
{ 0, 0, 0, 0, 0, 0, 0 },
};
GDrawFunctions *funcs;
const char *s;
GLint n;
// check for the extensions we need
s = (const char *) glGetString(GL_EXTENSIONS);
if (s == NULL) {
assert(s != NULL); // if this is NULL, you're probably trying to create the device too early
return NULL;
}
// check for the extensions we won't work without
if (!hasext(s, "GL_ARB_multitexture") ||
!hasext(s, "GL_ARB_texture_compression") ||
!hasext(s, "GL_ARB_texture_mirrored_repeat") ||
!hasext(s, "GL_ARB_texture_non_power_of_two") || // with caveats - see below!
!hasext(s, "GL_ARB_vertex_buffer_object") ||
!hasext(s, "GL_EXT_framebuffer_object") ||
!hasext(s, "GL_ARB_shader_objects") ||
!hasext(s, "GL_ARB_vertex_shader") ||
!hasext(s, "GL_ARB_fragment_shader"))
return NULL;
// if user requests multisampling and HW doesn't support it, bail
if (!hasext(s, "GL_EXT_framebuffer_multisample") && msaa_samples > 1)
return NULL;
load_extensions();
funcs = create_context(w, h);
if (!funcs)
return NULL;
gdraw->tex_formats = tex_formats;
// check for optional extensions
gdraw->has_mapbuffer = true; // part of core VBO extension on regular GL
gdraw->has_depth24 = true; // we just assume.
gdraw->has_texture_max_level = true; // core on regular GL
if (hasext(s, "GL_EXT_packed_depth_stencil")) gdraw->has_packed_depth_stencil = true;
// we require ARB_texture_non_power_of_two - on actual HW, this may either give us
// "full" non-power-of-two support, or "conditional" non-power-of-two (wrap mode must
// be CLAMP_TO_EDGE, no mipmaps). figure out which it is using this heuristic by
// Unity's Aras Pranckevicius (thanks!):
// http://www.aras-p.info/blog/2012/10/17/non-power-of-two-textures/
//
// we use the second heuristic (texture size <8192 for cards without full NPOT support)
// since we don't otherwise use ARB_fragment_program and don't want to create a program
// just to be able to query MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB!
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n);
gdraw->has_conditional_non_power_of_two = n < 8192;
// clamp number of multisampling levels to max supported
if (msaa_samples > 1) {
glGetIntegerv(GL_MAX_SAMPLES, &n);
gdraw->multisampling = RR_MIN(msaa_samples, n);
}
opengl_check();
return funcs;
}

View File

@@ -0,0 +1,38 @@
#ifndef __RAD_INCLUDE_GDRAW_GL_H__
#define __RAD_INCLUDE_GDRAW_GL_H__
#include "rrCore.h"
#include "gdraw.h"
RADDEFSTART
typedef enum gdraw_gl_resourcetype
{
GDRAW_GL_RESOURCE_rendertarget,
GDRAW_GL_RESOURCE_texture,
GDRAW_GL_RESOURCE_vertexbuffer,
GDRAW_GL_RESOURCE__count,
} gdraw_gl_resourcetype;
struct IggyCustomDrawCallbackRegion;
extern int gdraw_GL_SetResourceLimits(gdraw_gl_resourcetype type, S32 num_handles, S32 num_bytes);
extern GDrawFunctions * gdraw_GL_CreateContext(S32 min_w, S32 min_h, S32 msaa_samples);
extern void gdraw_GL_DestroyContext(void);
extern void gdraw_GL_SetTileOrigin(S32 vx, S32 vy, U32 framebuffer); // framebuffer=FBO handle, or 0 for main frame buffer
extern void gdraw_GL_NoMoreGDrawThisFrame(void);
extern GDrawTexture *gdraw_GL_WrappedTextureCreate(S32 gl_texture_handle, S32 width, S32 height, rrbool has_mipmaps);
extern void gdraw_GL_WrappedTextureChange(GDrawTexture *tex, S32 new_gl_texture_handle, S32 new_width, S32 new_height, rrbool new_has_mipmaps);
extern void gdraw_GL_WrappedTextureDestroy(GDrawTexture *tex);
extern void gdraw_GL_BeginCustomDraw(struct IggyCustomDrawCallbackRegion *region, F32 *matrix);
extern void gdraw_GL_EndCustomDraw(struct IggyCustomDrawCallbackRegion *region);
extern GDrawTexture * RADLINK gdraw_GL_MakeTextureFromResource(U8 *resource_file, S32 resource_len, IggyFileTextureRaw *texture);
extern void RADLINK gdraw_GL_DestroyTextureFromResource(GDrawTexture *tex);
RADDEFEND
#endif