mirror of
https://github.com/reactos/wine.git
synced 2025-02-13 08:44:54 +00:00
wined3d: Move constant loading into target-specific files.
- Moves GLSL constant loading code into glsl_shader.c and out of the over-populated drawprim.c. - Creates a new file named arb_program_shader.c which will hold code specific to ARB_vertex_program & ARB_fragment_program. - Remove the constant loading calls from drawprim.c
This commit is contained in:
parent
7f18b4e5fa
commit
2d8e05f8a1
@ -9,6 +9,7 @@ EXTRAINCL = @X_CFLAGS@
|
||||
EXTRALIBS = -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
|
||||
|
||||
C_SRCS = \
|
||||
arb_program_shader.c \
|
||||
baseshader.c \
|
||||
basetexture.c \
|
||||
cubetexture.c \
|
||||
|
111
dlls/wined3d/arb_program_shader.c
Normal file
111
dlls/wined3d/arb_program_shader.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Pixel and vertex shaders implementation using ARB_vertex_program
|
||||
* and ARB_fragment_program GL extensions.
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* Copyright 2005 Oliver Stieber
|
||||
* Copyright 2006 Ivan Gyurdiev
|
||||
* Copyright 2006 Jason Green
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
#define GLINFO_LOCATION (*gl_info)
|
||||
|
||||
/********************************************************
|
||||
* ARB_[vertex/fragment]_program helper functions follow
|
||||
********************************************************/
|
||||
|
||||
/**
|
||||
* Loads floating point constants into the currently set ARB_vertex/fragment_program.
|
||||
* When @constants_set == NULL, it will load all the constants.
|
||||
*
|
||||
* @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
|
||||
* or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
|
||||
*/
|
||||
void shader_arb_load_constantsF(
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLuint target_type,
|
||||
unsigned max_constants,
|
||||
float* constants,
|
||||
BOOL* constants_set) {
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
|
||||
constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
|
||||
constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
|
||||
|
||||
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i * sizeof(float)]));
|
||||
checkGLcall("glProgramEnvParameter4fvARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
|
||||
*
|
||||
* We only support float constants in ARB at the moment, so don't
|
||||
* worry about the Integers or Booleans
|
||||
*/
|
||||
void shader_arb_load_constants(
|
||||
IWineD3DStateBlock* iface,
|
||||
char usePixelShader,
|
||||
char useVertexShader) {
|
||||
|
||||
IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
|
||||
WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants for vertex shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants for vertex shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
|
||||
WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
stateBlock->vertexShaderConstantF,
|
||||
stateBlock->set.vertexShaderConstantsF);
|
||||
}
|
||||
|
||||
if (usePixelShader) {
|
||||
|
||||
/* Load DirectX 9 float constants for pixel shader */
|
||||
shader_arb_load_constantsF(gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
stateBlock->pixelShaderConstantF,
|
||||
stateBlock->set.pixelShaderConstantsF);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Add more ARB_[vertex/fragment]_program specific code here */
|
@ -1742,174 +1742,6 @@ void drawStridedSoftwareVS(IWineD3DDevice *iface, WineDirect3DVertexStridedData
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Loads (pixel shader) samplers
|
||||
*/
|
||||
void drawPrimLoadPSamplersGLSL(
|
||||
IWineD3DDevice* iface) {
|
||||
|
||||
IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
|
||||
GLhandleARB programId = This->stateBlock->shaderPrgId;
|
||||
GLhandleARB name_loc;
|
||||
int i;
|
||||
char sampler_name[20];
|
||||
|
||||
if (programId == 0) {
|
||||
/* No GLSL program set - nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i< GL_LIMITS(textures); ++i) {
|
||||
if (This->stateBlock->textures[i] != NULL) {
|
||||
snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
|
||||
name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
|
||||
if (name_loc != -1) {
|
||||
TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
|
||||
GL_EXTCALL(glUniform1iARB(name_loc, i));
|
||||
checkGLcall("glUniform1iARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads floating point constants (aka uniforms) into the currently set GLSL program.
|
||||
* When @constants_set == NULL, it will load all the constants.
|
||||
*/
|
||||
void drawPrimLoadConstantsGLSL_F(IWineD3DDevice* iface,
|
||||
unsigned max_constants,
|
||||
float* constants,
|
||||
BOOL* constants_set,
|
||||
char is_pshader) {
|
||||
|
||||
IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
|
||||
GLhandleARB programId = This->stateBlock->shaderPrgId;
|
||||
GLhandleARB tmp_loc;
|
||||
int i;
|
||||
char tmp_name[7];
|
||||
|
||||
if (programId == 0) {
|
||||
/* No GLSL program set - nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
||||
const char* prefix = is_pshader? "PC":"VC";
|
||||
|
||||
TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
|
||||
i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
|
||||
|
||||
/* TODO: Benchmark and see if it would be beneficial to store the
|
||||
* locations of the constants to avoid looking up each time */
|
||||
snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
|
||||
if (tmp_loc != -1) {
|
||||
/* We found this uniform name in the program - go ahead and send the data */
|
||||
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i*4]));
|
||||
checkGLcall("glUniform4fvARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads floating point constants into the currently set ARB_vertex/fragment_program.
|
||||
* When @constants_set == NULL, it will load all the constants.
|
||||
*
|
||||
* @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
|
||||
* or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
|
||||
*/
|
||||
void drawPrimLoadConstantsARB_F(IWineD3DDevice* iface,
|
||||
GLuint target_type,
|
||||
unsigned max_constants,
|
||||
float* constants,
|
||||
BOOL* constants_set) {
|
||||
|
||||
IWineD3DDeviceImpl* This = (IWineD3DDeviceImpl *)iface;
|
||||
int i;
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
TRACE_(d3d_shader)("Loading constants %i: %f, %f, %f, %f\n",
|
||||
i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
|
||||
|
||||
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, &constants[i*4]));
|
||||
checkGLcall("glProgramEnvParameter4fvARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the constants/uniforms which were passed by the application into either GLSL or ARB shader programs. */
|
||||
void drawPrimLoadConstants(IWineD3DDevice *iface,
|
||||
BOOL useVertexShader,
|
||||
BOOL usePixelShader) {
|
||||
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) This->stateBlock->vertexShader;
|
||||
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants/uniforms for vertex shader */
|
||||
drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL, 0);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for vertex shader */
|
||||
drawPrimLoadConstantsGLSL_F(iface, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
This->stateBlock->vertexShaderConstantF,
|
||||
This->stateBlock->set.vertexShaderConstantsF, 0);
|
||||
|
||||
/* TODO: Load boolean & integer constants for vertex shader */
|
||||
}
|
||||
if (usePixelShader) {
|
||||
|
||||
/* Load pixel shader samplers */
|
||||
drawPrimLoadPSamplersGLSL(iface);
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for pixel shader */
|
||||
drawPrimLoadConstantsGLSL_F(iface, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
This->stateBlock->pixelShaderConstantF,
|
||||
This->stateBlock->set.pixelShaderConstantsF, 1);
|
||||
|
||||
/* TODO: Load boolean & integer constants for pixel shader */
|
||||
}
|
||||
} else if (wined3d_settings.shader_mode == SHADER_ARB) {
|
||||
|
||||
/* We only support float constants in ARB at the moment, so don't
|
||||
* worry about the Integers or Booleans */
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants for vertex shader */
|
||||
drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants for vertex shader */
|
||||
drawPrimLoadConstantsARB_F(iface, GL_VERTEX_PROGRAM_ARB, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
This->stateBlock->vertexShaderConstantF,
|
||||
This->stateBlock->set.vertexShaderConstantsF);
|
||||
}
|
||||
if (usePixelShader) {
|
||||
|
||||
/* Load DirectX 9 float constants for pixel shader */
|
||||
drawPrimLoadConstantsARB_F(iface, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
This->stateBlock->pixelShaderConstantF,
|
||||
This->stateBlock->set.pixelShaderConstantsF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void inline drawPrimitiveDrawStrided(IWineD3DDevice *iface, BOOL useVertexShaderFunction, BOOL usePixelShaderFunction, int useHW, WineDirect3DVertexStridedData *dataLocations,
|
||||
UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idxData, short idxSize, int minIndex, long StartIdx) {
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
@ -2055,7 +1887,11 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||
}
|
||||
|
||||
/* Load any global constants/uniforms that may have been set by the application */
|
||||
drawPrimLoadConstants(iface, useVertexShaderFunction, usePixelShaderFunction);
|
||||
if (wined3d_settings.shader_mode == SHADER_GLSL)
|
||||
shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
||||
else if (wined3d_settings.shader_mode == SHADER_ARB)
|
||||
shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
||||
|
||||
|
||||
/* DirectX colours are in a different format to opengl colours
|
||||
* so if diffuse or specular are used then we need to use drawStridedSlow
|
||||
|
@ -47,6 +47,119 @@ void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (pixel shader) samplers
|
||||
*/
|
||||
void shader_glsl_load_psamplers(
|
||||
WineD3D_GL_Info *gl_info,
|
||||
IWineD3DStateBlock* iface) {
|
||||
|
||||
IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
|
||||
GLhandleARB programId = stateBlock->shaderPrgId;
|
||||
GLhandleARB name_loc;
|
||||
int i;
|
||||
char sampler_name[20];
|
||||
|
||||
for (i=0; i< GL_LIMITS(textures); ++i) {
|
||||
if (stateBlock->textures[i] != NULL) {
|
||||
snprintf(sampler_name, sizeof(sampler_name), "psampler%d", i);
|
||||
name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
|
||||
if (name_loc != -1) {
|
||||
TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
|
||||
GL_EXTCALL(glUniform1iARB(name_loc, i));
|
||||
checkGLcall("glUniform1iARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads floating point constants (aka uniforms) into the currently set GLSL program.
|
||||
* When @constants_set == NULL, it will load all the constants.
|
||||
*/
|
||||
void shader_glsl_load_constantsF(
|
||||
WineD3D_GL_Info *gl_info,
|
||||
GLhandleARB programId,
|
||||
unsigned max_constants,
|
||||
float* constants,
|
||||
BOOL* constants_set,
|
||||
char is_pshader) {
|
||||
|
||||
GLhandleARB tmp_loc;
|
||||
int i;
|
||||
char tmp_name[7];
|
||||
const char* prefix = is_pshader? "PC":"VC";
|
||||
|
||||
for (i=0; i<max_constants; ++i) {
|
||||
if (NULL == constants_set || constants_set[i]) {
|
||||
|
||||
TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
|
||||
constants[i * sizeof(float) + 0], constants[i * sizeof(float) + 1],
|
||||
constants[i * sizeof(float) + 2], constants[i * sizeof(float) + 3]);
|
||||
|
||||
/* TODO: Benchmark and see if it would be beneficial to store the
|
||||
* locations of the constants to avoid looking up each time */
|
||||
snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
|
||||
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
|
||||
if (tmp_loc != -1) {
|
||||
/* We found this uniform name in the program - go ahead and send the data */
|
||||
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, &constants[i * sizeof(float)]));
|
||||
checkGLcall("glUniform4fvARB");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the app-supplied constants into the currently set GLSL program.
|
||||
*/
|
||||
void shader_glsl_load_constants(
|
||||
IWineD3DStateBlock* iface,
|
||||
char usePixelShader,
|
||||
char useVertexShader) {
|
||||
|
||||
IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
|
||||
WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
|
||||
GLhandleARB programId = stateBlock->shaderPrgId;
|
||||
|
||||
if (programId == 0) {
|
||||
/* No GLSL program set - nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (useVertexShader) {
|
||||
IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
|
||||
IWineD3DVertexDeclarationImpl* vertexDeclaration =
|
||||
(IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
|
||||
|
||||
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
|
||||
/* Load DirectX 8 float constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
vertexDeclaration->constants, NULL, 0);
|
||||
}
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for vertex shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
|
||||
stateBlock->vertexShaderConstantF,
|
||||
stateBlock->set.vertexShaderConstantsF, 0);
|
||||
|
||||
/* TODO: Load boolean & integer constants for vertex shader */
|
||||
}
|
||||
|
||||
if (usePixelShader) {
|
||||
|
||||
/* Load pixel shader samplers */
|
||||
shader_glsl_load_psamplers(gl_info, iface);
|
||||
|
||||
/* Load DirectX 9 float constants/uniforms for pixel shader */
|
||||
shader_glsl_load_constantsF(gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
|
||||
stateBlock->pixelShaderConstantF,
|
||||
stateBlock->set.pixelShaderConstantsF, 1);
|
||||
|
||||
/* TODO: Load boolean & integer constants for pixel shader */
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions to generate GLSL strings from DirectX Shader bytecode begin here.
|
||||
*
|
||||
|
@ -1344,12 +1344,22 @@ extern const SHADER_OPCODE* shader_get_opcode(
|
||||
IWineD3DBaseShader *iface,
|
||||
const DWORD code);
|
||||
|
||||
/* ARB_[vertex/fragment]_program helper functions */
|
||||
extern void shader_arb_load_constants(
|
||||
IWineD3DStateBlock* iface,
|
||||
char usePixelShader,
|
||||
char useVertexShader);
|
||||
|
||||
/* ARB shader program Prototypes */
|
||||
extern void shader_hw_def(SHADER_OPCODE_ARG *arg);
|
||||
|
||||
/* GLSL helper functions */
|
||||
extern void set_glsl_shader_program(IWineD3DDevice *iface);
|
||||
extern void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG *arg);
|
||||
extern void shader_glsl_load_constants(
|
||||
IWineD3DStateBlock* iface,
|
||||
char usePixelShader,
|
||||
char useVertexShader);
|
||||
|
||||
/** The following translate DirectX pixel/vertex shader opcodes to GLSL lines */
|
||||
extern void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user